<?php

namespace Database\Seeders\Initial;

use App\Models\User;
use App\Models\Budget;
use App\Enums\UserType;
use App\Models\Company;
use App\Models\Category;
use App\Models\UnitType;
use App\Enums\BudgetStatusType;
use App\Models\Department;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;

class BudgetSeeder extends Seeder
{
  public function run(): void
  {
    $company = Company::first();
    if (!$company) {
      $company = Company::create([
        'code' => 'DEF',
        'name' => 'Default Company',
      ]);
    }

    $user = User::whereRole(UserType::User)->first();
    $department = Department::when($company, function ($query) use ($company) {
      $query->where('company_id', $company->id);
    })
      ->when($user->role !== UserType::PresidentDirector, function ($query) use ($user) {
        $query->whereHas('userDepartments', function ($q) use ($user) {
          $q->where('user_id', $user->id);
        });
      })
      ->first();

    $unitTypes = UnitType::all()->pluck('id', 'code'); // Map code => id

    $budgetsData = [
      [
        'name' => 'RENCANA ANGGARAN BIAYA PERSIAPAN MESS KARYAWAN GUNUNG SARI DAN OPERASIONAL PERSIAPAN MAPING',
        'date' => '2026-01-13',
        'year' => '2026',
        'description' => '',
        'details' => [
          [
            'category_name' => 'BBM',
            'items' => [
              [
                'name' => 'BBM',
                'quantity_unit' => [['quantity' => 1, 'unit_type_id' => 'unit']],
                'price' => 1100000,
                'description' => 'Hilux B 9845 UBE',
              ],
              [
                'name' => 'BBM',
                'quantity_unit' => [['quantity' => 1, 'unit_type_id' => 'unit']],
                'price' => 1100000,
                'description' => 'Hilux B 9847 UBE',
              ],
              [
                'name' => 'BBM',
                'quantity_unit' => [['quantity' => 1, 'unit_type_id' => 'lsn']],
                'price' => 3500000,
                'description' => 'Stock Untuk Hilux Ditabang',
              ],
              [
                'name' => 'BBM (PP)',
                'quantity_unit' => [['quantity' => 2, 'unit_type_id' => 'unit']],
                'price' => 1100000,
                'description' => 'BBM Hilux Pak Otong dan Pak Masing',
              ],
              [
                'name' => 'BBM (200 Liter)',
                'quantity_unit' => [['quantity' => 1, 'unit_type_id' => 'lsn']],
                'price' => 3800000,
                'description' => 'Untuk isi BBM Excavator 1 unit saja',
              ],
              [
                'name' => 'Pompa Robin 2 Inc',
                'quantity_unit' => [['quantity' => 1, 'unit_type_id' => 'unit']],
                'price' => 3500000,
                'description' => 'U/ pengisian dari Tanki stock BBM ke Unit',
              ],
            ]
          ],
          [
            'category_name' => 'PERLENGKAPAN MESS GN. SARI',
            'items' => [
              [
                'name' => 'Ranjang Spring Bed uk.120',
                'quantity_unit' => [['quantity' => 4, 'unit_type_id' => 'set']],
                'price' => 2600000,
                'description' => 'Merk Marcel',
              ],
              [
                'name' => 'Kasur (Spring) uk.120',
                'quantity_unit' => [['quantity' => 6, 'unit_type_id' => 'pcs']],
                'price' => 1200000,
                'description' => 'Merk Marcel',
              ],
              [
                'name' => 'Bantal',
                'quantity_unit' => [['quantity' => 10, 'unit_type_id' => 'pcs']],
                'price' => 70000,
                'description' => '',
              ],
              [
                'name' => 'Seprai',
                'quantity_unit' => [['quantity' => 10, 'unit_type_id' => 'pcs']],
                'price' => 70000,
                'description' => 'Inc: Sarung bantal',
              ],
              [
                'name' => 'Mesin Cuci 1 Tabung',
                'quantity_unit' => [['quantity' => 1, 'unit_type_id' => 'unit']],
                'price' => 4500000,
                'description' => '7 KG',
              ],
              [
                'name' => 'Freezer Box Horizontal (merk sharp)',
                'quantity_unit' => [['quantity' => 1, 'unit_type_id' => 'unit']],
                'price' => 3800000,
                'description' => '300 liter',
              ],
              [
                'name' => 'Lemari Pakaian Plastik 4 susun',
                'quantity_unit' => [['quantity' => 4, 'unit_type_id' => 'unit']],
                'price' => 280000,
                'description' => 'Napolly',
              ],
              [
                'name' => 'Batterai Remote AC',
                'quantity_unit' => [['quantity' => 4, 'unit_type_id' => 'pcs']],
                'price' => 6000,
                'description' => 'A3',
              ],
              [
                'name' => 'Batterai Jam Dinding',
                'quantity_unit' => [['quantity' => 6, 'unit_type_id' => 'pcs']],
                'price' => 6000,
                'description' => 'A2',
              ],
              [
                'name' => 'Service AC',
                'quantity_unit' => [['quantity' => 7, 'unit_type_id' => 'unit']],
                'price' => 100000,
                'description' => '',
              ],
              [
                'name' => 'Bola Lampu',
                'quantity_unit' => [['quantity' => 12, 'unit_type_id' => 'pcs']],
                'price' => 56000,
                'description' => '18 Watt',
              ],
              [
                'name' => 'Stick Untuk pasang bola lampu',
                'quantity_unit' => [['quantity' => 1, 'unit_type_id' => 'pcs']],
                'price' => 50000,
                'description' => '',
              ],
              [
                'name' => 'Keset Kaki Kain',
                'quantity_unit' => [['quantity' => 5, 'unit_type_id' => 'pcs']],
                'price' => 12000,
                'description' => 'Mess Gn. Sari',
              ],
              [
                'name' => 'Keset Kaki Karet',
                'quantity_unit' => [['quantity' => 5, 'unit_type_id' => 'pcs']],
                'price' => 36000,
                'description' => 'Mess Gn. Sari',
              ],
              [
                'name' => 'Pengharum Ruangan',
                'quantity_unit' => [['quantity' => 10, 'unit_type_id' => 'bks']],
                'price' => 18000,
                'description' => '',
              ],
              [
                'name' => 'Kapur Barus Toilet',
                'quantity_unit' => [['quantity' => 5, 'unit_type_id' => 'bks']],
                'price' => 32000,
                'description' => '',
              ],
              [
                'name' => 'Rak Piring',
                'quantity_unit' => [['quantity' => 1, 'unit_type_id' => 'unit']],
                'price' => 700000,
                'description' => '',
              ],
              [
                'name' => 'Kabel NYM 2x1,5MM',
                'quantity_unit' => [['quantity' => 1, 'unit_type_id' => 'roll']],
                'price' => 250000,
                'description' => '',
              ],
              [
                'name' => 'Terminal Kuningan 4 Lobang',
                'quantity_unit' => [['quantity' => 7, 'unit_type_id' => 'pcs']],
                'price' => 25000,
                'description' => '',
              ],
              [
                'name' => 'Kepala Colokan',
                'quantity_unit' => [['quantity' => 7, 'unit_type_id' => 'pcs']],
                'price' => 5000,
                'description' => '',
              ],
              [
                'name' => 'WIFI (starlink)',
                'quantity_unit' => [['quantity' => 1, 'unit_type_id' => 'unit']],
                'price' => 0,
                'description' => 'HO Jakarta yg handle',
              ],
              [
                'name' => 'Genset 10 KVA Hartech',
                'quantity_unit' => [['quantity' => 1, 'unit_type_id' => 'unit']],
                'price' => 0,
                'description' => 'Mess Gn. Sari',
              ],
              [
                'name' => 'Genset 25 KVA Hartech',
                'quantity_unit' => [['quantity' => 1, 'unit_type_id' => 'unit']],
                'price' => 0,
                'description' => 'Kontainer',
              ],
            ]
          ],
          [
            'category_name' => 'KONSUMSI',
            'items' => [
              [
                'name' => 'Makan Karyawan',
                'quantity_unit' => [
                  ['quantity' => 9, 'unit_type_id' => 'org'],
                  ['quantity' => 3, 'unit_type_id' => 'kali'],
                  ['quantity' => 30, 'unit_type_id' => 'hr'],
                ],
                'price' => 50000,
                'description' => '3x Makan untuk 30 Hari',
              ]
            ]
          ],
          [
            'category_name' => 'AKOMODASI',
            'items' => [
              [
                'name' => 'Penginapan di Beb Bareb',
                'quantity_unit' => [
                  ['quantity' => 7, 'unit_type_id' => 'kmr'],
                  ['quantity' => 7, 'unit_type_id' => 'hr'],
                ],
                'price' => 250000,
                'description' => '9 Orang',
              ]
            ]
          ]
        ]
      ],
      [
        'name' => 'RENCANA ANGGARAN BIAYA OPERASIONAL DAN KEPERLUAN SEHARI-HARI KANTOR',
        'date' => '2026-02-10',
        'year' => '2026',
        'description' => 'Kebutuhan rutin ATK, kebersihan, dan konsumsi pantry kantor.',
        'details' => [
          [
            'category_name' => 'ALAT TULIS KANTOR',
            'items' => [
              [
                'name' => 'Kertas HVS A4 80gr',
                'quantity_unit' => [['quantity' => 10, 'unit_type_id' => 'rim']],
                'price' => 55000,
                'description' => 'Sinar Dunia / Paperline',
              ],
              [
                'name' => 'Tinta Printer Epson (Set)',
                'quantity_unit' => [['quantity' => 2, 'unit_type_id' => 'set']],
                'price' => 450000,
                'description' => 'Seri 003 (CMYK) untuk Printer L3110',
              ],
              [
                'name' => 'Alat Tulis & Binder Clip',
                'quantity_unit' => [['quantity' => 1, 'unit_type_id' => 'lsn']],
                'price' => 250000,
                'description' => 'Pulpen, spidol whiteboard, dan klip kertas',
              ],
            ]
          ],
          [
            'category_name' => 'Konsumsi',
            'items' => [
              [
                'name' => 'Air Mineral Galon',
                'quantity_unit' => [['quantity' => 20, 'unit_type_id' => 'gln']],
                'price' => 20000,
                'description' => 'Konsumsi staf dan tamu (Aqua)',
              ],
              [
                'name' => 'Kopi, Teh, dan Gula',
                'quantity_unit' => [['quantity' => 1, 'unit_type_id' => 'lsn']],
                'price' => 350000,
                'description' => 'Stok bulanan pantry',
              ],
            ]
          ],
          [
            'category_name' => 'Kebersihan',
            'items' => [
              [
                'name' => 'Peralatan Kebersihan',
                'quantity_unit' => [['quantity' => 1, 'unit_type_id' => 'lsn']],
                'price' => 300000,
                'description' => 'Cairan pembersih lantai, sabun cuci tangan, dan tissue',
              ],
              [
                'name' => 'Listrik & Internet',
                'quantity_unit' => [['quantity' => 1, 'unit_type_id' => 'bln']],
                'price' => 2500000,
                'description' => 'Estimasi biaya utilitas bulanan',
              ],
            ]
          ]
        ]
      ]
    ];

    foreach ($budgetsData as $data) {
      $modelData = [
        'name' => $data['name'],
        'date' => $data['date'],
        'year' => $data['year'],
        'description' => $data['description'],
        'company_id' => $company->id,
        'user_id' => $user ? $user->id : 1,
        'department_id' => $department ? $department->id : 1,
        'status' => BudgetStatusType::Draft,
        'debit_amount' => 0,
        'credit_amount' => 0,
      ];

      $budgetCode = "$department->code/" . date('m') . "/" . date('Y');
      $lastBudget = DB::table("budgets")
        ->select("code")
        ->where('company_id', $company->id)
        ->latest("id")
        ->whereNotNull('code')
        ->first();

      $modelData['code'] = "0001/$budgetCode";

      if ($lastBudget) {
        $lastCode = explode("/", $lastBudget->code);
        $lastCode = $lastCode[0];

        if ($lastCode) {
          $lastCode = str_pad(intval($lastCode) + 1, 4, "0", STR_PAD_LEFT);
          $modelData['code'] = "$lastCode/$budgetCode";
        }
      }

      $budget = Budget::create($modelData);

      if (empty($data['details']))
        continue;

      $budgetDetailCode = $budget->code;
      $budgetDetailNumber = 0;
      $totalDebitAmount = 0;

      foreach ($data['details'] as $detailGroup) {
        $categoryName = $detailGroup['category_name'];
        $category = Category::where(DB::raw("LOWER(name)"), strtolower($categoryName))->first();
        if (!$category) {
          $categoryName = str($categoryName)->title()->toString();
          $category = Category::create([
            'name' => $categoryName,
          ]);
        }

        if ($user) {
          $exists = DB::table('user_categories')
            ->where('user_id', $user->id)
            ->where('category_id', $category->id)
            ->exists();

          if (!$exists) {
            try {
              DB::table('user_categories')->insert([
                'user_id' => $user->id,
                'category_id' => $category->id,
                'department_id' => 1,
                'created_at' => now(),
                'updated_at' => now(),
              ]);
            } catch (\Exception $e) {
            }
          }
        }

        $groupTotal = 0;

        $budgetCategory = $budget->budgetCategories()->create([
          'category_id' => $category->id,
          'price_amount_total' => 0,
        ]);

        foreach ($detailGroup['items'] as $item) {
          $budgetDetailNumber++;

          // Calculate total quantity by multiplying all quantities (e.g., 5 Box * 10 Pcs = 50 items if intended, or just 5*10 dim)
          // User request: "hasil perkalian dari semua quantity yang ditambahkan"

          $itemTotalQuantity = 1;
          $hasQuantityUnit = false;

          if (!empty($item['quantity_unit'])) {
            foreach ($item['quantity_unit'] as $qu) {
              $val = floatval($qu['quantity']);
              $itemTotalQuantity *= ($val ?: 1); // Avoid 0 if empty, but if 0 input, it becomes 0? Users usually input >=1
              $hasQuantityUnit = true;
            }
          }

          if (!$hasQuantityUnit)
            $itemTotalQuantity = 0;

          $price = intval($item['price']);
          $total = $itemTotalQuantity * $price;
          $groupTotal += $total;

          $budgetDetail = $budgetCategory->budgetDetails()->create([
            'budget_id' => $budget->id,
            'code' => sprintf("%s/%04d", $budgetDetailCode, $budgetDetailNumber),
            'name' => $item['name'],
            'price' => $price,
            'price_total' => $total,
            'description' => $item['description'] ?? null,
            'user_id' => $budget->user_id,
            'status' => $budget->status,
          ]);

          if (isset($item['quantity_unit'])) {
            foreach ($item['quantity_unit'] as $qu) {
              $unitTypeId = $unitTypes[$qu['unit_type_id']] ?? null;
              if ($unitTypeId) {
                $budgetDetail->quantityUnits()->create([
                  'quantity' => $qu['quantity'],
                  'unit_type_id' => $unitTypeId
                ]);
              }
            }
          }
        }

        $budgetCategory->update(['price_amount_total' => $groupTotal]);
        $totalDebitAmount += $groupTotal;
      }

      $budget->update(['debit_amount' => $totalDebitAmount]);
    }
  }
}
