<?php

namespace App\Console\Commands;

use App\Mail\InvoiceTransitMail;
use App\Models\AlertMailRule;
use App\Models\InvoiceInTransit;
use App\Models\InvoiceMaster;
use App\Models\Plant;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;

class SendInvoiceTransitReport extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'send:invoice-transit-report {schedule_type} {plant}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Command description';

    /**
     * Execute the console command.
     */
    public function handle()
    {

        $scheduleType = $this->argument('schedule_type');
        $plantId = (int) $this->argument('plant');

        $mailRules = AlertMailRule::where('module', 'InvoiceTransit')
            ->where('rule_name', 'InvoiceTransitMail')
            ->where('schedule_type', $scheduleType)
            ->where('plant', $plantId)
            ->get();

        $plants = ($plantId == 0)
            ? Plant::all()
            : Plant::where('id', $plantId)->get();

        $plantCodes = $plants->pluck('name', 'id');

        if ($plants->isEmpty()) {
            $this->error('No valid plant(s) found.');

            return;
        }

        $todayRecordExists = InvoiceInTransit::whereDate('created_at', now()->toDateString())->first();

        if (!$todayRecordExists) {
            $this->info('No records created today. Mail not sent.');
            return;
        }

        if (strtolower($scheduleType) == 'daily') {
            $results = DB::table('invoice_in_transits as it')
                ->join('invoice_masters as im', function ($join) {
                    $join->on('im.receiving_plant_name', '=', 'it.receiving_plant_name')->on('im.transport_name', '=', 'it.transport_name');
                })
                ->select(
                    'it.invoice_number',
                    'it.receiving_plant',
                    'it.plant_id',
                    'it.receiving_plant_name',
                    'it.lr_bl_aw_date',
                    'it.lr_bl_aw_number',
                    'im.id as invoice_master_id',
                    'im.transport_name',
                    DB::raw('CAST(im.transit_days AS INTEGER) as transit_days'),
                    // DB::raw('(CURRENT_DATE - CAST(it.lr_bl_aw_date AS DATE)) as delayed_days')
                    // DB::raw('
                    //     GREATEST(
                    //         0,
                    //         (CURRENT_DATE - CAST(it.lr_bl_aw_date AS DATE) - 1)
                    //         - CAST(im.transit_days AS INTEGER)
                    //     ) AS delayed_days
                    // ')
                    DB::raw('
                        GREATEST(
                            1,
                            (CURRENT_DATE - CAST(it.lr_bl_aw_date AS DATE))
                            - CAST(im.transit_days AS INTEGER)
                        ) AS delayed_days
                    ')

                )
                ->when($plantId != 0, fn ($q) => $q->where('it.plant_id', $plantId))
                ->whereNotNull('it.lr_bl_aw_date')
                ->whereRaw('
                    (CURRENT_DATE - CAST(it.lr_bl_aw_date AS DATE))
                    - CAST(im.transit_days AS INTEGER) > 0
                ')
                ->distinct('it.invoice_number')
                ->get();

            if ($results->isEmpty()) {
                $this->info('No invoice transit records found for today.');

                return;
            }

            $tableData = [];

            foreach ($mailRules as $rule) {

                $ruleInvoices = $results->where('invoice_master_id', $rule->invoice_master_id);
                // $ruleInvoices = $results->filter(fn($item) => $item->invoice_master_id == (int)$rule->invoice_master_id);

                if ($ruleInvoices->isEmpty()) {
                    $this->info("Skipping rule {$rule->id} — no invoice transit data.");

                    continue;
                }

                $invoiceMaster = InvoiceMaster::find($rule->invoice_master_id);

                $mailSubject = $invoiceMaster
                ? "Despatch Invoice In Transit ({$invoiceMaster->receiving_plant_name} - {$invoiceMaster->transport_name})"
                : 'Despatch Invoice In Transit';

                if ($ruleInvoices->isEmpty()) {
                    $tableData = [];
                    $this->info("No despatch invoices in transit found for rule {$rule->id}.");
                } else {

                    $tableData = $ruleInvoices->values()->map(function ($item, $index) use ($plantCodes) {
                        return [
                            'no' => $index + 1,
                            'plant' => $plantCodes[$item->plant_id],
                            'receiving_plant' => $item->receiving_plant,
                            'receiving_plant_name' => $item->receiving_plant_name,
                            'invoice_number' => $item->invoice_number,
                            'transport_name' => $item->transport_name,
                            'lr_bl_aw_date' => $item->lr_bl_aw_date,
                            'lr_bl_aw_number' => $item->lr_bl_aw_number,
                            'transit_days' => $item->transit_days,
                            'status' => $item->delayed_days.' Days',
                        ];
                    })->toArray();

                }

                $mail = new InvoiceTransitMail($scheduleType, $tableData, $mailSubject);

                $toEmails = collect(explode(',', $rule->email))
                    ->map(fn ($e) => trim($e))
                    ->filter()
                    ->unique()
                    ->values()
                    ->toArray();

                $ccEmails = collect(explode(',', $rule->cc_emails))
                    ->map(fn ($e) => trim($e))
                    ->filter()
                    ->unique()
                    ->values()
                    ->toArray();

                if (empty($toEmails)) {
                    $this->warn("Skipping rule {$rule->id} — no To emails.");

                    continue;
                }

                \Mail::to($toEmails)->cc($ccEmails)->send($mail);

                $this->info(
                    "Mail sent → Rule {$rule->id} | Invoice Master ID: {$rule->invoice_master_id} | To: ".implode(', ', $toEmails)
                );
            }
        }
    }
}
