<?php

namespace App\Http\Controllers\Reports;

use App\Http\Controllers\Controller;
use App\Cawangan;
use App\Gadai;
use App\Customer;
use App\Tebus;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use App\Services\Reports\GadaianService as ReportGadaianService;
use App\Helper;
use Carbon\Carbon;
use App\Pekerjaan;
use App\Poskod;
use App\TransactionOnline;
use Log;
use App\Services\Reports\RingkasanHarianService as ReportRingkasanHarianService;


class AnalisaController extends Controller
{
    public function getLaporanCawangan(string $kod_cawangan, Request $request)
    {
        $reportGadaianService = new ReportGadaianService($kod_cawangan, $request);
        return $reportGadaianService->getCawanganReport();
    }

    public function getSummaryLaporanPelangganBaru(Request $request)
    {
        $startDate = $request->startDate;
        $endDate = $request->endDate;

        // Get active branch DBs from helper
        $active_cawangan_db_connection = Helper::getActiveCawanganDbConnection();

        // Fetch branch details with mysql info
        $cawangan_available = Cawangan::select('kodcaw', 'details_caw', 'mysql')
            ->whereIn('mysql', $active_cawangan_db_connection)
            ->get();

        $active_cawangan_db_connection = array_column($cawangan_available->toArray(), 'mysql');

        $active_cawangan_detail = $cawangan_available->map(function ($c) {
            return [
                'kodcaw' => $c->kodcaw,
                'details_caw' => $c->details_caw,
            ];
        })->values()->toArray();

        // Iterate through each branch and get data
        $response = array_map(function ($db_connection, $cawangan_detail) use ($request) {
            // Pass the required parameters to the service constructor
            $reportRingkasanHarianService = new ReportRingkasanHarianService($cawangan_detail['kodcaw'], $request);
    
            // Get the customer count from the service
            $bilangan_customer_baru = $reportRingkasanHarianService->getCustomerSummary(); // Call public method
    
            // Return the response
            return [
                'kodcaw' => $cawangan_detail['kodcaw'],
                'details_caw' => $cawangan_detail['details_caw'],
                'total_pelanggan_baru' => $bilangan_customer_baru,
            ];
        }, $active_cawangan_db_connection, $active_cawangan_detail);

        return response()->json($response);
    }

    // public function getSummaryLaporanPelangganAktif(Request $request)
    // {
    //     $startDate = $request->startDate;
    //     $endDate = $request->endDate;

    //     // Dapatkan senarai cawangan aktif
    //     $active_cawangan_db_connection = Helper::getActiveCawanganDbConnection();

    //     // Dapatkan maklumat cawangan
    //     $cawangan_available = Cawangan::select('kodcaw', 'details_caw', 'mysql')
    //         ->whereIn('mysql', $active_cawangan_db_connection)
    //         ->get();

    //     $active_cawangan_detail = $cawangan_available->map(function ($c) {
    //         return [
    //             'kodcaw' => $c->kodcaw,
    //             'details_caw' => $c->details_caw,
    //             'mysql' => $c->mysql,
    //         ];
    //     })->toArray();

    //    $response = array_map(function ($cawangan) use ($startDate, $endDate) {
    //     $db_connection = $cawangan['mysql'];

    //     $total_aktif = Gadai::on($db_connection)
    //         ->where(function ($query) use ($startDate) {
    //             $query->where('sttebus', '')
    //                 ->where('t_update', '>=', $startDate);
    //         })
    //         ->where('t_gadai', '<=', $endDate)
    //         ->distinct('nokp')
    //         ->count('nokp');

    //     return [
    //         'kodcaw' => $cawangan['kodcaw'],
    //         'details_caw' => $cawangan['details_caw'],
    //         'total_pelanggan_aktif' => $total_aktif,
    //     ];
    // }, $active_cawangan_detail);


    //     return response()->json($response);
    // }


public function getSummaryLaporanPelangganAktif(Request $request)
{
    $startDate = $request->startDate;
    $endDate = $request->endDate;

    $active_cawangan = Cawangan::select('kodcaw', 'details_caw', 'mysql')
        ->whereIn('mysql', Helper::getActiveCawanganDbConnection())
        ->get();

    $response = $active_cawangan->map(function ($cawangan) use ($startDate, $endDate) {
        $db = $cawangan->mysql;

        // Ambil nokp dari Gadai
        $nokp_gadai = DB::connection($db)->table('gadai')
            ->whereBetween('t_gadai', [$startDate, $endDate])
            ->pluck('nokp')
            ->toArray();

        // Ambil nokp dari Tebus
        $nokp_tebus = DB::connection($db)->table('tebus as t')
            ->join('gadai as g', 't.norujukan', '=', 'g.norujukan')
            ->whereBetween('t.t_tebus', [$startDate, $endDate])
            ->pluck('g.nokp')
            ->toArray();

        // Gabung semua nokp
       $semua_nokp = collect(array_merge($nokp_gadai, $nokp_tebus))
        ->filter(fn($item) => !empty($item))
        ->unique()
        ->values();

    if ($semua_nokp->isEmpty()) {
        // Jika array kosong, kita kembalikan hasil kosong
        $pelanggan_aktif = collect();
    } else {
       $pelanggan_aktif = Customer::on($db)
        ->where(function ($query) use ($semua_nokp) {
            $query->whereIn('kpbaru', $semua_nokp)
                ->orWhereIn('kplama', $semua_nokp);
        })
        ->get(['nama', 'kpbaru', 'kplama'])
         ->toArray();;
    }

        return [
            'kodcaw' => $cawangan->kodcaw,
            'details_caw' => $cawangan->details_caw,
            'total_pelanggan_aktif' => count($semua_nokp),
        ];
    });

    return response()->json($response);
}

    public function getActiveCawanganConnections()
    {
        $cawangan_details = Cawangan::select(['details_caw', 'mysql'])->get();

        $cawangan_details = $cawangan_details->filter(fn($x) => !in_array(strtolower($x->details_caw), config('report.excluded_cawangan')));

        $connection_active_cawangan = Helper::getActiveCawanganDbConnection();

        return collect($cawangan_details->filter(fn($x) => in_array($x->mysql, $connection_active_cawangan)));

    }

    public function getSummaryLaporanDataPelanggan(Request $request)
    {
        $year = $request->year;
        if (!$year) {
            return response()->json(['error' => 'Sila pilih tahun'], 400);
        }

        $startOfYear = Carbon::create($year, 1, 1)->startOfDay();
        $endOfYear   = Carbon::create($year, 12, 31)->endOfDay();

        Carbon::setLocale('ms');

        // 1️⃣ Ambil semua pelanggan tahun ini
        $pelanggan = Customer::whereYear('tarikhdaftar', $year)
            ->select('id','nama','kpbaru','kplama','t_lahir','jantina',
                    'kodkerja','poskod','kodcaw','tarikhdaftar','tujuangadai','nopelanggan')
            ->get();

        $connections = $this->getActiveCawanganConnections();

        // Ambil semua pekerjaan & poskod sekali untuk map cepat
        $pekerjaanAll = Pekerjaan::pluck('keterangan','kodkerja');
        $poskodAll = Poskod::with('daerah')->get()->keyBy('poskod');

        // 2️⃣ Ambil semua nokp pelanggan
        $nokps = $pelanggan->map(fn($p) => $p->kpbaru ?? $p->kplama)->filter()->values();

        // 3️⃣ Ambil semua transaksi gadai + tebus untuk nokp tu dari semua cawangan
        $allTransaksi = collect();
        foreach ($connections as $conn) {
            $data = DB::connection($conn->mysql)
            ->table('gadai as g')
            ->leftJoin('tebus as t', 'g.norujukan', '=', 't.norujukan')
            ->leftJoin('lelong as l', 'g.norujukan', '=', 'l.norujukan')
            ->whereIn('g.nokp', $nokps)
            ->whereBetween('g.t_gadai', [$startOfYear, $endOfYear]) // ⬅️ dalam tahun sahaja
            ->select(
                'g.nokp',
                'g.norujukan',
                'g.t_gadai',
                't.t_tebus',
                'g.pinjaman',
                'g.upah12',
                'g.tempoh',
                'l.t_lelong',
                'g.sttebus',
            )
            ->get();
            $allTransaksi = $allTransaksi->concat($data);
        }

        // 4️⃣ Group by nokp
        $transGrouped = $allTransaksi->groupBy('nokp');

        // 5️⃣ Ambil semua norujukan transaksi online
        $onlineNorujukan = TransactionOnline::pluck('norujukan')->unique()->values();
        

        // 6️⃣ Map pelanggan
        $result = $pelanggan->map(function($row) use ($transGrouped, $onlineNorujukan, $pekerjaanAll, $poskodAll, $year) {

            $nokp = $row->kpbaru ?? $row->kplama ?? null;

            $tempohData = $transGrouped->get($nokp, collect());

            // Norujukan pelanggan spesifik
            $norujukanPelanggan = $tempohData->pluck('norujukan')->unique()->values();

            // Cara Bayaran
            // $caraBayaran = $norujukanPelanggan->intersect($onlineNorujukan)->isNotEmpty() ? 'Online' : 'Kaunter';
            $adaOnline = $norujukanPelanggan->contains(fn($nr) => isset($onlineNorujukan[$nr]));
            $caraBayaran = $adaOnline ? 'Online' : 'Kaunter';
            if ($adaOnline) {
                \Log::info("Pelanggan {$row->nama} ({$nokp}): Bayaran Online - YA");
            }



            // Bilangan transaksi
            $bilTransaksi = $tempohData->count();

            // Bilangan Belum tebus
            $endOfYear = Carbon::create($year, 12, 31)->endOfDay();
            $bilOutstanding = $tempohData
            ->filter(function ($row) use ($endOfYear) {

                // masih belum tebus langsung
                if (empty($row->sttebus)) {
                    return true;
                }

                // dah tebus, tapi tebus selepas hujung tahun
                return Carbon::parse($row->t_tebus)->gt($endOfYear);
            })
            ->count();

            // Bilangan tebus
            $bilTebus = $tempohData->whereNotNull('t_tebus')->count();

            // Jumlah pinjaman
            $jumlahPinjaman = $tempohData->sum('pinjaman');

            // Jumlah ujrah ikut tempoh surat
            $jumlahUjrah = $tempohData->reduce(function ($carry, $trx) {
                if (!$trx->upah12 || !$trx->tempoh) return $carry;
                return $carry + ($trx->upah12 / 12 * $trx->tempoh);
            }, 0);

            // Tarikh mula & tamat
            $tarikhMula = $tempohData->min('t_gadai');
            $tarikhTamat = $tempohData->max('t_tebus');
            $tarikhLelong = $tempohData->max('t_lelong');

            // Tempoh Pajakan
            if (!$tarikhMula) {
                $tempohPajakan = '-';
            } elseif (!$tarikhTamat || $tarikhMula == $tarikhTamat) {
                $tempohPajakan = Carbon::parse($tarikhMula)->translatedFormat('M Y');
            } else {
                $tempohPajakan = Carbon::parse($tarikhMula)->translatedFormat('M Y') . 
                                ' - ' . 
                                Carbon::parse($tarikhTamat)->translatedFormat('M Y');
            }

            // Hari sejak transaksi terakhir
            $hariTempohPajakan = $tarikhMula
                ? Carbon::parse($tarikhMula)->diffInDays($tarikhTamat ? Carbon::parse($tarikhTamat) : Carbon::now())
                : null;

            // Tujuan gadai
            $tujuangadai = $row->tujuangadai ?: '-';

            // Status aktif: ada transaksi dalam tahun tu
            $now = Carbon::now();

            $endOfYear = Carbon::create($year, 12, 31)->endOfDay();
            $startOfYear = Carbon::create($year, 1, 1)->startOfDay();

            $statusAktif = $tempohData->contains(function ($trx) use ($startOfYear, $endOfYear) {

                if (!$trx->t_gadai) return false;

                $tGadai = Carbon::parse($trx->t_gadai);
                $tTebus = $trx->t_tebus ? Carbon::parse($trx->t_tebus) : null;

                // SAG wujud dalam tahun laporan
                return
                    $tGadai->lte($endOfYear) &&
                    (
                        is_null($tTebus) ||      // belum ditebus
                        $tTebus->gte($startOfYear) // ditebus dalam / selepas tahun
                    );
            });

            // Umur
            $umur = $row->t_lahir ? Carbon::parse($row->t_lahir)->age : null;

            // Pekerjaan
            $pekerjaan = $row->kodkerja 
                ? ($pekerjaanAll[ltrim($row->kodkerja,'0')] ?? 'Lain-lain')
                : '-';

            // Daerah / lokasi
            $lokasi = $row->poskod && isset($poskodAll[$row->poskod])
                ? $poskodAll[$row->poskod]->daerah->namadaerah ?? 'Lain-lain'
                : 'Lain-lain';

            return [
                'cawangan'             => $row->kodcaw ?? '-',
                'nama'                 => $row->nama,
                'nopelanggan'          => $row->nopelanggan,
                'nokp'                 => $nokp ?? '-',
                'tarikhdaftar'         => Carbon::parse($row->tarikhdaftar)->format('d-m-Y'),
                'umur'                 => $umur,
                'jantina'              => $row->jantina ?? '-',
                'pekerjaan'            => $pekerjaan,
                'daerah'               => $lokasi,
                'tempoh_pajakan'       => $tempohPajakan,
                'tarikh_mula'          => $tarikhMula ? Carbon::parse($tarikhMula)->format('d-m-Y') : null,
                'tarikh_tamat'         => $tarikhTamat ? Carbon::parse($tarikhTamat)->format('d-m-Y') : null,
                'hari_sejak_transaksi' => $hariTempohPajakan,
                'bil_transaksi'        => $bilTransaksi,
                'bil_outstanding'      => $bilOutstanding,
                'bil_tebus'            => $bilTebus,
                'jumlah_pinjaman'      => $jumlahPinjaman,
                'norujukan'            => $norujukanPelanggan,
                'jumlah_ujrah'         => $jumlahUjrah,
                'tujuan_gadai'         => $tujuangadai,
                'status_aktif'         => $statusAktif ? 'AKTIF' : 'TIDAK AKTIF',
                'cara_bayaran'         => $caraBayaran,
                'tarikh_lelong'        => $tarikhLelong ? Carbon::parse($tarikhLelong)->format('d-m-Y') : null,
            ];
        });

        return response()->json([
            'year' => $year,
            'summary' => [
                'total_pelanggan' => $result->count(),
                'jumlah_cawangan' => $result->pluck('cawangan')->unique()->count(),
            ],
            'pelanggan' => $result->values(),
        ], 200);
    }
    
    private function formatTempohPajakan($start, $end)
    {
        if (!$start || !$end) {
            return '-';
        }

        $mula  = Carbon::parse($start);
        $tamat = Carbon::parse($end);

        if ($mula->year === $tamat->year) {
            return $mula->translatedFormat('M') . ' – ' .
                   $tamat->translatedFormat('M Y');
        }

        return $mula->translatedFormat('M Y') . ' – ' .
               $tamat->translatedFormat('M Y');
    }


    public function getSummaryLaporanDataPelangganBycaw(Request $request)
    {
        $year = $request->year;
        if (!$year) {
            return response()->json(['error' => 'Sila pilih tahun'], 400);
        }

        // ===============================
        // INPUT CAWANGAN (MULTIPLE)
        // ===============================
        $cawangan = $request->input('cawangan', []);

        if (!is_array($cawangan)) {
            $cawangan = [$cawangan];
        }

        
        $startOfYear = Carbon::create($year, 1, 1)->startOfDay();
        $endOfYear   = Carbon::create($year, 12, 31)->endOfDay();

        Carbon::setLocale('ms');

        // ===============================
        // 1️⃣ AMBIL PELANGGAN (FILTER CAWANGAN)
        // ===============================
        $pelangganQuery = Customer::whereYear('tarikhdaftar', $year);

        if (!empty($cawangan)) {
            $pelangganQuery->whereIn('kodcaw', $cawangan);
        }

        $pelanggan = $pelangganQuery
            ->select(
                'id','nama','kpbaru','kplama','t_lahir','jantina',
                'kodkerja','poskod','kodcaw','tarikhdaftar',
                'tujuangadai','nopelanggan'
            )
            ->get();

        if ($pelanggan->isEmpty()) {
            return response()->json([
                'year' => $year,
                'summary' => [
                    'total_pelanggan' => 0,
                    'jumlah_cawangan' => 0,
                ],
                'pelanggan' => []
            ], 200);
        }

        // ===============================
        // 2️⃣ CONNECTION CAWANGAN
        // ===============================
        $connections = $this->getActiveCawanganConnections();
        
        // ===============================
        // 3️⃣ MASTER DATA
        // ===============================
        $pekerjaanAll = Pekerjaan::pluck('keterangan', 'kodkerja');
        $poskodAll    = Poskod::with('daerah')->get()->keyBy('poskod');

        // ===============================
        // 4️⃣ NOKP PELANGGAN
        // ===============================
        $nokps = $pelanggan
            ->map(fn($p) => $p->kpbaru ?? $p->kplama)
            ->filter()
            ->values();

        // ===============================
        // 5️⃣ TRANSAKSI GADAI / TEBUS
        // ===============================
        $allTransaksi = collect();

        foreach ($connections as $conn) {
            $data = DB::connection($conn->mysql)
                ->table('gadai as g')
                ->leftJoin('tebus as t', 'g.norujukan', '=', 't.norujukan')
                ->leftJoin('lelong as l', 'g.norujukan', '=', 'l.norujukan')
                ->whereIn('g.nokp', $nokps)
                ->whereBetween('g.t_gadai', [$startOfYear, $endOfYear])
                ->select(
                    'g.nokp',
                    'g.norujukan',
                    'g.t_gadai',
                    't.t_tebus',
                    'g.pinjaman',
                    'g.upah12',
                    'g.tempoh',
                    'l.t_lelong',
                    'g.sttebus'
                )
                ->get();

            $allTransaksi = $allTransaksi->concat($data);
        }

        $transGrouped = $allTransaksi->groupBy('nokp');

        // ===============================
        // 6️⃣ NORUJUKAN BAYARAN ONLINE
        // ===============================
        $onlineNorujukan = TransactionOnline::pluck('norujukan')->unique();

        // ===============================
        // 7️⃣ MAP DATA PELANGGAN
        // ===============================
        $result = $pelanggan->map(function ($row) use (
            $transGrouped,
            $onlineNorujukan,
            $pekerjaanAll,
            $poskodAll,
            $year
        ) {

            $nokp = $row->kpbaru ?? $row->kplama;

            $tempohData = $transGrouped->get($nokp, collect());

            $norujukanPelanggan = $tempohData->pluck('norujukan')->unique();

            // Cara Bayaran
            $adaOnline = $norujukanPelanggan
                ->intersect($onlineNorujukan)
                ->isNotEmpty();

            $caraBayaran = $adaOnline ? 'Online' : 'Kaunter';

            // Bilangan
            $bilTransaksi = $tempohData->count();

            $bilOutstanding = $tempohData->filter(function ($row) use ($year) {
                $endOfYear = Carbon::create($year, 12, 31)->endOfDay();

                if (empty($row->sttebus)) return true;

                return Carbon::parse($row->t_tebus)->gt($endOfYear);
            })->count();

            $bilTebus = $tempohData->whereNotNull('t_tebus')->count();

            // Jumlah
            $jumlahPinjaman = $tempohData->sum('pinjaman');

            $jumlahUjrah = $tempohData->reduce(function ($carry, $trx) {
                if (!$trx->upah12 || !$trx->tempoh) return $carry;
                return $carry + ($trx->upah12 / 12 * $trx->tempoh);
            }, 0);

            // Tarikh
            $tarikhMula   = $tempohData->min('t_gadai');
            $tarikhTamat  = $tempohData->max('t_tebus');
            $tarikhLelong = $tempohData->max('t_lelong');

            // Tempoh Pajakan
            if (!$tarikhMula) {
                $tempohPajakan = '-';
            } elseif (!$tarikhTamat || $tarikhMula == $tarikhTamat) {
                $tempohPajakan = Carbon::parse($tarikhMula)->translatedFormat('M Y');
            } else {
                $tempohPajakan =
                    Carbon::parse($tarikhMula)->translatedFormat('M Y') .
                    ' - ' .
                    Carbon::parse($tarikhTamat)->translatedFormat('M Y');
            }

            // Hari sejak transaksi terakhir
            $hariTempohPajakan = $tarikhMula
                ? Carbon::parse($tarikhMula)->diffInDays($tarikhTamat ? Carbon::parse($tarikhTamat) : Carbon::now())
                : null;

            // Tujuan gadai
            $tujuangadai = $row->tujuangadai ?: '-';

            // Status aktif: ada transaksi dalam tahun tu
            $now = Carbon::now();

            // Status Aktif
            $startOfYear = Carbon::create($year, 1, 1)->startOfDay();
            $endOfYear   = Carbon::create($year, 12, 31)->endOfDay();

            $statusAktif = $tempohData->contains(function ($trx) use ($startOfYear, $endOfYear) {
                if (!$trx->t_gadai) return false;

                $tGadai = Carbon::parse($trx->t_gadai);
                $tTebus = $trx->t_tebus ? Carbon::parse($trx->t_tebus) : null;

                return $tGadai->lte($endOfYear) &&
                    (is_null($tTebus) || $tTebus->gte($startOfYear));
            });

            // Umur
            $umur = $row->t_lahir ? Carbon::parse($row->t_lahir)->age : null;

            // Pekerjaan
            $pekerjaan = $row->kodkerja
                ? ($pekerjaanAll[ltrim($row->kodkerja, '0')] ?? 'Lain-lain')
                : '-';

            // Daerah
            $lokasi = $row->poskod && isset($poskodAll[$row->poskod])
                ? ($poskodAll[$row->poskod]->daerah->namadaerah ?? 'Lain-lain')
                : 'Lain-lain';

            
            return [
                'cawangan'        => $row->kodcaw,
                'nama'            => $row->nama,
                'nopelanggan'     => $row->nopelanggan,
                'nokp'            => $nokp,
                'tarikhdaftar'    => Carbon::parse($row->tarikhdaftar)->format('d-m-Y'),
                'umur'            => $umur,
                'jantina'         => $row->jantina,
                'pekerjaan'       => $pekerjaan,
                'daerah'          => $lokasi,
                'tempoh_pajakan'  => $tempohPajakan,
                'tarikh_mula'     => $tarikhMula ? Carbon::parse($tarikhMula)->format('d-m-Y') : null,
                'tarikh_tamat'    => $tarikhTamat ? Carbon::parse($tarikhTamat)->format('d-m-Y') : null,
                'hari_sejak_transaksi' => $hariTempohPajakan,
                'bil_transaksi'   => $bilTransaksi,
                'bil_outstanding' => $bilOutstanding,
                'bil_tebus'       => $bilTebus,
                'jumlah_pinjaman' => $jumlahPinjaman,
                'jumlah_ujrah'    => $jumlahUjrah,
                'tujuan_gadai'    => $tujuangadai,
                'cara_bayaran'    => $caraBayaran,
                'status_aktif'    => $statusAktif ? 'AKTIF' : 'TIDAK AKTIF',
                'tarikh_lelong'   => $tarikhLelong
                    ? Carbon::parse($tarikhLelong)->format('d-m-Y')
                    : null,
            ];
        });

        $result = $result->sortBy('cawangan')->values();

        return response()->json([
            'year' => $year,
            'cawangan' => $cawangan,
            'summary' => [
                'total_pelanggan' => $result->count(),
                'jumlah_cawangan' => $result->pluck('cawangan')->unique()->count(),
            ],
            'pelanggan' => $result,
        ], 200);
    }
}
