<?php

namespace App\Services\Reports;

use App\Cawangan;
use App\CawanganDetail;
use App\Customer;
use App\Gadai;
use App\Helper;
use App\Transaction;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\Request;

class AnsuranService
{

    public $kod_cawangan;
    public $startDate;
    public $endDate;

    public function __construct($kod_cawangan, Request $request)
    {
        $this->kod_cawangan = $kod_cawangan;
        $this->startDate = $request->startDate;
        $this->endDate = $request->endDate;
    }

    public function getCawanganReport()
    {
        $online_array_db_connection = Helper::getOnlineArrahnConnection();
        $cawangan_connection = Cawangan::where('kodcaw', $this->kod_cawangan)->first()->mysql;

        $query_total_ansuran = Transaction::on($online_array_db_connection)
            ->where('transaction.kodcaw', $this->kod_cawangan)
            ->leftJoin('transaksi_keuntungan', function ($join) {
                $join->on('transaction.norujukan', '=', 'transaksi_keuntungan.norujukan');
                $join->on('transaction.created_at', '=', 'transaksi_keuntungan.tarikh_bayaran');
            })
            ->where('transaction.trans_type', '=', 'A')
            ->whereDate('transaction.created_at', '>=', date($this->startDate))
            ->whereDate('transaction.created_at', '<=', date($this->endDate));

        $total_ansuran = $this->getTotalAnsuran($query_total_ansuran);
        $total_summary_ansuran_teller = $this->getTotalSummaryAnsuranGroupByTeller($query_total_ansuran);
        $total_summary_ansuran = $this->getTotalSummaryAnsuran($query_total_ansuran);
        $gadaian_ansuran = $this->getGadaianAnsuran($cawangan_connection, $total_ansuran->pluck('norujukan'));
        $customer_info = $this->getCustomerInfo($gadaian_ansuran);
        $cawangan_detail = $this->getCawanganDetail($cawangan_connection);

        $total_ansuran = $total_ansuran->zip($gadaian_ansuran, $customer_info)->map(function ($data) {
            [$ansuran, $gadaian_ansuran, $customer_info] = $data;

            return [
                'norujukan' => $ansuran->norujukan,
                'nama' => $customer_info['nama'],
                'no_kp' => $gadaian_ansuran['nokp'],
                'teller' => $ansuran->teller,
                'bayaran_pembiayaan' => $ansuran->bayaran_pembiayaan,
                'bayaran_keuntungan' => $ansuran->bayaran_kos_keuntungan,
                'jumlah_ansuran' => $ansuran->jumlah_bayaran,
            ];
        });

         // **Tidak Group By Teller** untuk keseluruhan laporan
        $total_ansuran_keseluruhan = $total_ansuran->map(function ($ansuran) {
            return [
                'norujukan' => $ansuran['norujukan'],
                'nama' => $ansuran['nama'],
                'no_kp' => $ansuran['no_kp'],
                'bayaran_pembiayaan' => $ansuran['bayaran_pembiayaan'],
                'bayaran_keuntungan' => $ansuran['bayaran_keuntungan'],
                'jumlah_ansuran' => $ansuran['jumlah_ansuran'],
            ];
        });

        $total_ansuran = $total_ansuran->groupBy('teller');

        $ansuran_tellers = $total_ansuran->keys();

        $total_ansuran = $total_ansuran
            ->zip($total_summary_ansuran_teller)
            ->map(function ($data) {

                [$ansuran, $summary] = $data;

                return [
                    'ansuran' => $ansuran,
                    'summary_ansuran_teller' => $summary,
                ];
            });

        $total_ansuran = $ansuran_tellers->combine($total_ansuran);

        $data = [
            'query' => [
                'startDate' => Helper::formatDate($this->startDate),
                'endDate' => Helper::formatDate($this->endDate),
            ],
            'cawangan_detail' => $cawangan_detail,
            'total_ansuran' => $total_ansuran,
            'total_ansuran_keseluruhan' => $total_ansuran_keseluruhan, // Tambahkan keseluruhan laporan
            'summary_ansuran' => $total_summary_ansuran,
        ];

        ray($data);
        return json_encode($data);

    }

    private function getTotalAnsuran($query_total_ansuran)
    {
        $total_ansuran = (clone $query_total_ansuran)
            ->selectRaw('
                transaction.norujukan as norujukan,
                transaksi_keuntungan.bayaran_pembiayaan as bayaran_pembiayaan,
                transaksi_keuntungan.bayaran_keuntungan as bayaran_kos_keuntungan,
                transaction.duit_masuk as jumlah_bayaran,
                teller
               ');

        return $total_ansuran->get();

    }

    private function getCawanganDetail($cawangan_connection)
    {
        $cawangan_detail = CawanganDetail::on($cawangan_connection)->get()
            ->map(function ($detail) {
                return [
                    'nama' => $detail['namacaw'],
                    'code' => $detail['kodcaw'] . ' Ar-Rahn ' . $detail['cawangan'],
                    'alamat' => $detail['alamat1'],
                    'waktu_operasi' => $detail['alamat4'],
                ];
            });

        return $cawangan_detail[0];

    }

    private function getTotalSummaryAnsuran(Builder $query_total_ansuran)
    {

        $total_ansuran = (clone $query_total_ansuran)
            ->selectRaw('
                count(transaction.norujukan) as sum_norujukan,
                sum(transaksi_keuntungan.bayaran_pembiayaan) as sum_bayaran_pembiayaan,
                sum(transaksi_keuntungan.bayaran_keuntungan) as sum_bayaran_kos_keuntungan,
                sum(transaction.duit_masuk) as sum_jumlah_bayaran,
                teller
               ');

        return $total_ansuran->get()->toArray()[0];
    }
    private function getTotalSummaryAnsuranGroupByTeller(Builder $query_total_ansuran)
    {

        $total_summary_ansuran_groupByTeller = (clone $query_total_ansuran)
            ->selectRaw('
                count(transaction.norujukan) as sum_norujukan,
                sum(transaksi_keuntungan.bayaran_pembiayaan) as sum_bayaran_pembiayaan,
                sum(transaksi_keuntungan.bayaran_keuntungan) as sum_bayaran_kos_keuntungan,
                sum(transaction.duit_masuk) as sum_jumlah_bayaran,
                teller
               ')
            ->groupBy('transaction.teller')
            ->get()
            ->toArray();

        return $total_summary_ansuran_groupByTeller;
    }

    private function getCustomerInfo($total_ansuran)
    {

        $extract_nokp = $total_ansuran->pluck('nokp');

        $customer_info = Customer::on('mysql7')
            ->select(['nama', 'alamat1', 'kpbaru', 'kplama'])
            ->where(function ($query) use ($extract_nokp) {
                $query->whereIn('kpbaru', $extract_nokp)
                    ->orWhereIn('kplama', $extract_nokp);
            })
            ->get();

        $customer_info = collect($extract_nokp)->map(function ($nokp) use ($customer_info) {
            return $customer_info->where('kpbaru', $nokp)->first() ?? $customer_info->where('kplama', $nokp)->first();
        })->toArray();

        return $customer_info;
    }

    private function getGadaianAnsuran($cawangan_connection, $list_norujukan)
    {

        $gadaian_ansuran = Gadai::on($cawangan_connection)
            ->whereIn('norujukan', $list_norujukan)
            ->select('norujukan', 'nokp')
            ->get();

        $norujukan_key = $gadaian_ansuran->pluck('norujukan');

        $norujukan_dictionary = array_combine($norujukan_key->toArray(), $gadaian_ansuran->toArray());

        return $list_norujukan->map(function($norujukan) use($norujukan_dictionary){
           return $norujukan_dictionary[$norujukan];
        });

    }

}
