<?php
namespace App\Controllers;

use App\Core\Controller;
use App\Core\Dates;
use App\Core\Num;
use App\Core\Request;
use App\Services\AcpService;
use App\Services\AgingService;
use App\Services\DashboardService;
use App\Services\ExportService;

/** Dashboard keuangan interaktif. */
class DashboardController extends Controller
{
    protected string $module = 'dashboard';

    /** Membaca filter dashboard dari query string. */
    private function readFilters(): array
    {
        $f = [];
        foreach (['area_id', 'business_unit_id', 'customer_id', 'outlet_id', 'salesperson_id',
                  'collection_officer_id', 'job_category_id', 'revenue_category_id', 'payment_status_code'] as $k) {
            $v = Request::get($k, '');
            if ($v !== '' && $v !== null) $f[$k] = $v;
        }
        foreach (['invoice_date_from', 'invoice_date_to', 'due_date_from', 'due_date_to'] as $k) {
            $v = Request::date($k);
            if ($v) $f[$k] = $v;
        }
        if (Request::get('hanya_outstanding')) $f['hanya_outstanding'] = 1;
        return $f;
    }

    public function index(): void
    {
        $asOf    = Request::date('tanggal_lapor') ?: Dates::today();
        $filters = $this->readFilters();
        $agingId = Request::int('aging_config', 0) ?: null;
        $acpMethod = in_array(Request::get('metode_acp', ''), ['finansial', 'operasional'], true)
                   ? Request::get('metode_acp') : null;

        $svc = new DashboardService($filters, $asOf);

        $this->view('dashboard/index', [
            'judul'    => 'Dashboard',
            'subjudul' => 'Ringkasan piutang per ' . Dates::fmtLong($asOf),
            'asOf'     => $asOf,
            'filters'  => $filters,
            'agingId'  => $agingId,
            'acpMethod'=> $acpMethod,
            'kpi'      => $svc->kpi(),
            'aging'    => $svc->agingComposition($agingId),
            'agingConfigs' => AgingService::allConfigs(),
            'arTrend'  => $svc->arTrend(12),
            'monthly'  => $svc->monthlyTrend(12),
            'acpTrend' => $svc->acpTrend(null, $acpMethod),
            'byArea'   => $svc->byDimension('area', 10),
            'bySales'  => $svc->byDimension('salesperson', 10),
            'byJob'    => $svc->byDimension('job_category', 10),
            'byBu'     => $svc->byDimension('business_unit', 5),
            'topCust'  => $svc->byDimension('customer', 10),
            'topOverdue' => $svc->byDimension('customer', 10, true),
            'paidVsUnpaid' => $svc->paidVsUnpaid(),
            'forecast' => $svc->collectionForecast(8),
            'worklist' => $svc->collectionSummary(),
            'opsi'     => DashboardService::filterOptions(),
        ]);
    }

    /** Endpoint JSON untuk pemuatan ulang chart tanpa refresh halaman. */
    public function data(): void
    {
        $asOf = Request::date('tanggal_lapor') ?: Dates::today();
        $svc  = new DashboardService($this->readFilters(), $asOf);
        $blok = (string)Request::get('blok', 'kpi');
        $out = match ($blok) {
            'aging'    => $svc->agingComposition(Request::int('aging_config', 0) ?: null),
            'ar_trend' => $svc->arTrend(Request::int('bulan', 12)),
            'monthly'  => $svc->monthlyTrend(Request::int('bulan', 12)),
            'acp'      => $svc->acpTrend(),
            'forecast' => $svc->collectionForecast(Request::int('minggu', 8)),
            'dimensi'  => $svc->byDimension((string)Request::get('dimensi', 'area'), Request::int('limit', 10)),
            default    => $svc->kpi(),
        };
        $this->json(['sukses' => true, 'data' => $out]);
    }

    /** Drill-down: mengalihkan ke daftar invoice dengan filter yang sesuai. */
    public function drill(): void
    {
        $q = $_GET;
        $jenis = (string)($q['jenis'] ?? '');
        unset($q['jenis']);
        $target = '/piutang';
        switch ($jenis) {
            case 'terlambat':          $q['payment_status_code'] = 'TERLAMBAT'; break;
            case 'jatuh_tempo':        $q['payment_status_code'] = 'JATUH_TEMPO'; break;
            case 'belum_jatuh_tempo':  $q['payment_status_code'] = 'BELUM_JATUH_TEMPO'; break;
            case 'sebagian':           $q['payment_status_code'] = 'PEMBAYARAN_SEBAGIAN'; break;
            case 'lunas':              $q['payment_status_code'] = 'LUNAS'; $target = '/invoice'; break;
            case 'dibatalkan':         $q['doc_status'] = 'cancelled'; $target = '/invoice'; break;
            case 'direvisi':           $q['doc_status'] = 'replaced'; $target = '/invoice'; break;
            case 'outstanding':        $q['hanya_outstanding'] = 1; break;
            case 'aging':              $target = '/aging/detail'; break;
            case 'semua':              $target = '/invoice'; break;
        }
        $this->redirect($target . ($q ? '?' . http_build_query($q) : ''));
    }

    public function export(): void
    {
        $asOf = Request::date('tanggal_lapor') ?: Dates::today();
        $svc = new DashboardService($this->readFilters(), $asOf);
        $k = $svc->kpi();
        $rows = [
            ['indikator' => 'Jumlah Invoice',                'nilai' => $k['jumlah_invoice'],   'tipe' => 'jumlah'],
            ['indikator' => 'Total Nominal Invoice (Bruto)', 'nilai' => $k['total_bruto'],      'tipe' => 'rupiah'],
            ['indikator' => 'Total Potongan',                'nilai' => $k['total_potongan'],   'tipe' => 'rupiah'],
            ['indikator' => 'Total Tagihan Bersih',          'nilai' => $k['total_bersih'],     'tipe' => 'rupiah'],
            ['indikator' => 'Total Pembayaran Diterima',     'nilai' => $k['total_pembayaran'], 'tipe' => 'rupiah'],
            ['indikator' => 'Total Saldo Piutang',           'nilai' => $k['total_saldo'],      'tipe' => 'rupiah'],
            ['indikator' => 'Piutang Terlambat',             'nilai' => $k['saldo_terlambat'],  'tipe' => 'rupiah'],
            ['indikator' => 'Piutang Jatuh Tempo Hari Ini',  'nilai' => $k['saldo_jatuh_tempo'],'tipe' => 'rupiah'],
            ['indikator' => 'Piutang Belum Jatuh Tempo',     'nilai' => $k['saldo_belum_jt'],   'tipe' => 'rupiah'],
            ['indikator' => 'Piutang Pembayaran Sebagian',   'nilai' => $k['saldo_sebagian'],   'tipe' => 'rupiah'],
            ['indikator' => 'Total PPh 23 Dipotong',         'nilai' => $k['total_pph23'],      'tipe' => 'rupiah'],
            ['indikator' => 'Revenue Diakui',                'nilai' => $k['total_revenue'],    'tipe' => 'rupiah'],
            ['indikator' => 'Invoice Dibatalkan',            'nilai' => $k['jumlah_dibatalkan'],'tipe' => 'jumlah'],
            ['indikator' => 'Invoice Direvisi',              'nilai' => $k['jumlah_direvisi'],  'tipe' => 'jumlah'],
            ['indikator' => 'Jumlah Customer Aktif',         'nilai' => $k['jumlah_customer'],  'tipe' => 'jumlah'],
            ['indikator' => 'Average Collection Period (hari)', 'nilai' => $k['acp'],           'tipe' => 'hari'],
            ['indikator' => 'Target ACP (hari)',             'nilai' => $k['acp_target'],       'tipe' => 'hari'],
            ['indikator' => 'Rata-rata Umur Piutang (hari)', 'nilai' => $k['rata_umur_piutang'],'tipe' => 'hari'],
            ['indikator' => 'Collection Rate (%)',           'nilai' => $k['collection_rate'],  'tipe' => 'persen'],
            ['indikator' => 'Overdue Rate (%)',              'nilai' => $k['overdue_rate'],     'tipe' => 'persen'],
            ['indikator' => 'Revenue Bulan Berjalan',        'nilai' => $k['revenue_bulan'],    'tipe' => 'rupiah'],
            ['indikator' => 'Penerimaan Bulan Berjalan',     'nilai' => $k['penerimaan_bulan'], 'tipe' => 'rupiah'],
        ];
        $data = array_map(fn($r) => [
            'indikator' => $r['indikator'],
            'nilai' => $r['nilai'],
            'satuan' => ['rupiah' => 'Rupiah', 'jumlah' => 'Dokumen', 'hari' => 'Hari', 'persen' => 'Persen'][$r['tipe']],
        ], $rows);

        ExportService::send((string)Request::get('format', 'xlsx'), [
            'judul' => 'RINGKASAN KPI DASHBOARD PIUTANG',
            'tanggal_lapor' => Dates::fmt($asOf),
            'nama_berkas' => 'dashboard_kpi',
            'sheet' => 'KPI Dashboard',
            'orientasi' => 'portrait',
        ], [
            ['label' => 'Indikator', 'key' => 'indikator', 'type' => 'text', 'width' => 44],
            ['label' => 'Nilai',     'key' => 'nilai',     'type' => 'dec',  'width' => 22],
            ['label' => 'Satuan',    'key' => 'satuan',    'type' => 'text', 'width' => 14],
        ], $data);
    }
}
