<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;

use App\Models\Tenant;
use App\Models\Unit;
use App\Models\Lease;
use App\Models\Invoice;
use App\Models\InvoiceItem;
use App\Models\Payment;
use App\Models\PaymentAllocation;

class RukoBerkahUmiHistoricalSeeder extends Seeder
{
    public function run(): void
    {
        /**
         * =========================
         * KONFIGURASI WAJIB
         * =========================
         * Pastikan Units sudah ada dengan name persis:
         * "Ruko 1", "Ruko 2", "Ruko 3", "Ruko 4"
         */

        // Mapping unit berdasarkan NAMA
        $unitIds = Unit::query()
            ->whereIn('name', ['Ruko 1','Ruko 2','Ruko 3','Ruko 4'])
            ->pluck('id','name')
            ->toArray();

        foreach (['Ruko 1','Ruko 2','Ruko 3','Ruko 4'] as $uName) {
            if (!isset($unitIds[$uName])) {
                throw new \RuntimeException("Unit '{$uName}' tidak ditemukan. Pastikan master Units sudah diisi.");
            }
        }

        /**
         * =========================
         * TENANT PER RUKO
         * =========================
         */
        $tenantByRuko = [
            'Ruko 1' => 'Penyewa Existing 1',
            'Ruko 2' => 'Penyewa Existing 2',
            'Ruko 3' => 'Penyewa Existing 3',
            'Ruko 4' => 'Penyewa Existing 4',
        ];

        // create / get tenant
        $tenantIds = [];
        foreach ($tenantByRuko as $rukoName => $tenantName) {
            $tenant = Tenant::firstOrCreate(
                ['name' => $tenantName],
                [
                    'phone' => null,
                    'email' => null,
                    'address' => null,
                    'notes' => 'Auto created by historical seeder',
                    'is_active' => 1,
                ]
            );
            $tenantIds[$rukoName] = $tenant->id;
        }

        /**
         * =========================
         * LEASE DUMMY (agar lease_id tidak null)
         * =========================
         * 1 lease per ruko-tenant, status ended.
         */
        $leaseIds = [];
        foreach ($tenantByRuko as $rukoName => $tenantName) {
            $tenantId = $tenantIds[$rukoName];
            $unitId   = $unitIds[$rukoName];

            $lease = Lease::firstOrCreate(
                [
                    'unit_id' => $unitId,
                    'tenant_id' => $tenantId,
                    'billing_cycle' => 'monthly',
                    'start_date' => '2023-07-01',
                    'end_date' => '2025-12-31',
                ],
                [
                    'price_amount' => 0,
                    'due_day' => null,
                    'yearly_anchor_month' => 8,
                    'prorate_enabled' => false,
                    'status' => 'ended',
                    'notes' => 'LEASE HISTORI (dummy) untuk impor rekap 2023-2025',
                ]
            );

            $leaseIds[$rukoName] = $lease->id;
        }

        /**
         * =========================
         * DATA HISTORIS (2023-2025)
         * =========================
         */

        $data = [];

        // 2023: Juli-Desember kosong
        for ($m = 7; $m <= 12; $m++) {
            $data[2023][$m] = [
                'Ruko 1' => 0,
                'Ruko 2' => 0,
                'Ruko 3' => 0,
                'Ruko 4' => 0,
            ];
        }

        // 2024
        $data[2024] = [
            1  => ['Ruko 1'=>800000,'Ruko 2'=>800000,'Ruko 3'=>750000,'Ruko 4'=>800000],
            2  => ['Ruko 1'=>800000,'Ruko 2'=>800000,'Ruko 3'=>750000,'Ruko 4'=>800000],
            3  => ['Ruko 1'=>800000,'Ruko 2'=>800000,'Ruko 3'=>750000,'Ruko 4'=>800000],
            4  => ['Ruko 1'=>800000,'Ruko 2'=>800000,'Ruko 3'=>750000,'Ruko 4'=>800000],
            5  => ['Ruko 1'=>800000,'Ruko 2'=>800000,'Ruko 3'=>0,'Ruko 4'=>800000],
            6  => ['Ruko 1'=>800000,'Ruko 2'=>800000,'Ruko 3'=>800000,'Ruko 4'=>800000],
            7  => ['Ruko 1'=>800000,'Ruko 2'=>800000,'Ruko 3'=>800000,'Ruko 4'=>0],
            8  => ['Ruko 1'=>800000,'Ruko 2'=>800000,'Ruko 3'=>800000,'Ruko 4'=>700000],
            9  => ['Ruko 1'=>800000,'Ruko 2'=>800000,'Ruko 3'=>800000,'Ruko 4'=>800000],
            10 => ['Ruko 1'=>800000,'Ruko 2'=>800000,'Ruko 3'=>800000,'Ruko 4'=>800000],
            11 => ['Ruko 1'=>800000,'Ruko 2'=>800000,'Ruko 3'=>100000,'Ruko 4'=>800000],
            12 => ['Ruko 1'=>800000,'Ruko 2'=>800000,'Ruko 3'=>0,'Ruko 4'=>800000],
        ];

        // 2025
        $data[2025] = [
            1  => ['Ruko 1'=>800000,'Ruko 2'=>800000,'Ruko 3'=>700000,'Ruko 4'=>825000],
            2  => ['Ruko 1'=>800000,'Ruko 2'=>800000,'Ruko 3'=>750000,'Ruko 4'=>825000],
            3  => ['Ruko 1'=>800000,'Ruko 2'=>800000,'Ruko 3'=>750000,'Ruko 4'=>825000],
            4  => ['Ruko 1'=>800000,'Ruko 2'=>800000,'Ruko 3'=>750000,'Ruko 4'=>825000],
            5  => ['Ruko 1'=>800000,'Ruko 2'=>800000,'Ruko 3'=>750000,'Ruko 4'=>825000],
            6  => ['Ruko 1'=>800000,'Ruko 2'=>800000,'Ruko 3'=>750000,'Ruko 4'=>800000],
            7  => ['Ruko 1'=>800000,'Ruko 2'=>800000,'Ruko 3'=>750000,'Ruko 4'=>800000],
            8  => ['Ruko 1'=>800000,'Ruko 2'=>750000,'Ruko 3'=>750000,'Ruko 4'=>700000],
            9  => ['Ruko 1'=>800000,'Ruko 2'=>750000,'Ruko 3'=>750000,'Ruko 4'=>700000],
            10 => ['Ruko 1'=>800000,'Ruko 2'=>750000,'Ruko 3'=>750000,'Ruko 4'=>700000],
            11 => ['Ruko 1'=>800000,'Ruko 2'=>750000,'Ruko 3'=>750000,'Ruko 4'=>700000],
            12 => ['Ruko 1'=>800000,'Ruko 2'=>750000,'Ruko 3'=>750000,'Ruko 4'=>700000],
        ];

        /**
         * =========================
         * EXECUTE INSERT
         * =========================
         * Invoice histori pakai bulan kalender (1 s/d akhir bulan) supaya cocok rekap Excel.
         * 1 invoice per ruko (tenant) per bulan.
         */
        DB::transaction(function () use ($data, $unitIds, $tenantIds, $leaseIds) {

            foreach ($data as $year => $months) {
                foreach ($months as $month => $row) {

                    $ps = Carbon::create($year, $month, 1)->startOfMonth();
                    $pe = $ps->copy()->endOfMonth();

                    foreach ($row as $rukoName => $amount) {
                        $amount = (int) $amount;
                        if ($amount <= 0) continue; // skip 0

                        $tenantId = $tenantIds[$rukoName];
                        $unitId   = $unitIds[$rukoName];
                        $leaseId  = $leaseIds[$rukoName];

                        // cegah dobel: invoice per tenant per bulan
                        $exists = Invoice::query()
                            ->where('tenant_id', $tenantId)
                            ->where('period_type', 'monthly')
                            ->whereDate('period_start', $ps->toDateString())
                            ->whereDate('period_end', $pe->toDateString())
                            ->where('status', '!=', 'void')
                            ->exists();

                        if ($exists) {
                            continue;
                        }

                        $invoice = Invoice::create([
                            'tenant_id'    => $tenantId,
                            'period_type'  => 'monthly',
                            'period_start' => $ps->toDateString(),
                            'period_end'   => $pe->toDateString(),
                            'due_date'     => $ps->toDateString(),
                            'total_amount' => $amount,
                            'paid_amount'  => $amount,
                            'status'       => 'paid',
                            'issued_at'    => $ps,
                            'paid_at'      => $pe,
                            'notes'        => "Histori impor {$rukoName} {$year}-" . str_pad((string)$month, 2, '0', STR_PAD_LEFT),
                        ]);

                        InvoiceItem::create([
                            'invoice_id'  => $invoice->id,
                            'lease_id'    => $leaseId, // tidak null
                            'unit_id'     => $unitId,
                            'description' => "Sewa {$rukoName} - {$ps->format('F Y')}",
                            'amount'      => $amount,
                        ]);

                        $receiptNo = sprintf('HIST-%d-%02d-%s', $year, $month, str_pad((string)$tenantId, 4, '0', STR_PAD_LEFT));

                        $payment = Payment::create([
                            'tenant_id'    => $tenantId,
                            'paid_at'      => $pe,
                            'method'       => 'cash',
                            'reference_no' => $receiptNo,
                            'total_amount' => $amount,
                            'receipt_no'   => $receiptNo,
                            'public_token' => Str::random(48),
                            'notes'        => "Histori pembayaran {$rukoName} {$ps->format('F Y')}",
                            'created_by'   => null,
                        ]);

                        PaymentAllocation::create([
                            'payment_id'     => $payment->id,
                            'invoice_id'     => $invoice->id,
                            'amount_applied' => $amount,
                        ]);

                        $invoice->recalcTotals();
                        $invoice->save();
                    }
                }
            }
        });
    }
}
