<?php

namespace App\Console\Commands;

use App\Mail\InvoiceDataMail;
use App\Models\AlertMailRule;
use App\Models\InvoiceDataValidation;
use App\Models\InvoiceOutValidation;
use App\Models\Plant;
use Illuminate\Console\Command;

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

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

    /**
     * Execute the console command.
     */
    public function handle()
    {
        // ini_set('max_execution_time', 0); // disable limit
        // set_time_limit(0);

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

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

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

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

            return;
        }

        // if (strtolower($scheduleType) == 'daily') {
        //     $startDate = now()->subDay()->setTime(10, 0, 0);//8:00
        //     $endDate = now()->setTime(10, 0, 0);//8
        // }

        if (strtolower($scheduleType) == 'daily') {
            $firstRecord = InvoiceDataValidation::orderBy('document_date', 'asc')->first();
            $lastRecord = InvoiceDataValidation::orderBy('document_date', 'desc')->first();

            if ($firstRecord && $lastRecord) {
                $startDate = \Carbon\Carbon::parse($firstRecord->document_date)->startOfDay();
                // $endDate = \Carbon\Carbon::parse($lastRecord->document_date)->endOfDay();
                $endDate = \Carbon\Carbon::parse($lastRecord->document_date)
                    ->addDay()
                    ->setTime(10, 0, 0);
            } else {
                $startDate = now()->startOfDay();
                $endDate = now()->endOfDay();
            }
        } else {
            $startDate = now()->setTime(8, 0, 0);
            $endDate = now()->copy()->addDay()->setTime(8, 0, 0);
        }

        // ..

        foreach ($plants as $plant) {
            $tableData = [];

            // $distributions = ['Direct Sale', 'Branch Sale', 'Internal Transfer', 'WOS', ''];
            $distributions = InvoiceDataValidation::whereNotNull('distribution_channel_desc')
                ->distinct()
                ->pluck('distribution_channel_desc')
                ->filter(fn ($val) => trim($val) != '')
                ->values()
                ->toArray();

            $distributions[] = '';

            foreach ($distributions as $selectedDistribution) {
                // where('plant_id', $plant->id)
                $invoices = InvoiceDataValidation::where('plant_id', $plant->id)
                    ->where('distribution_channel_desc', $selectedDistribution)
                    ->whereBetween('document_date', [$startDate, $endDate])
                    ->orderBy('document_date', 'asc')
                    ->select('customer_code', 'document_number', 'document_date', 'customer_trade_name', 'customer_location', 'location')
                    ->get()
                    ->unique('document_number')
                    ->values();

                if ($invoices->isEmpty()) {
                    continue;
                }

                // Filter invoices directly — exclude ones with '-' in document_number
                $invoices = $invoices->filter(function ($inv) {
                    return ! empty($inv->document_number) && ! str_contains($inv->document_number, '-');
                });

                if (trim($selectedDistribution) == '' || $selectedDistribution == null) {
                    $invoices = $invoices->filter(function ($inv) {
                        return str_starts_with($inv->document_number, '7');
                    });
                }

                if ($invoices->isEmpty()) {
                    continue;
                }

                $invoiceNumbers = $invoices
                    ->pluck('document_number')
                    ->map(fn ($n) => preg_replace('/\s+/', '', strtoupper((string) $n)))
                    ->toArray();

                // where('plant_id', $plant->id)
                $wentOutInvoices = InvoiceOutValidation::whereIn('qr_code', $invoiceNumbers)
                    // ->whereBetween('scanned_at', [$startDate, $endDate])
                    ->distinct('qr_code')
                    ->pluck('qr_code')
                    ->map(fn ($n) => preg_replace('/\s+/', '', strtoupper((string) $n)))
                    ->toArray();

                // if (!empty($wentOutInvoices)) {
                //     $deletedValidations = InvoiceDataValidation::whereIn('document_number', $wentOutInvoices)
                //         ->delete();

                //     $deletedOuts = InvoiceOutValidation::whereIn('qr_code', $wentOutInvoices)
                //         ->delete();

                //     $this->info("Deleted {$deletedValidations} from invoice_data_validations and {$deletedOuts} from invoice_out_validations for plant {$plant->name} ({$selectedDistribution}).");
                // }

                // $pendingInvoices = $invoices->filter(function ($inv) use ($wentOutInvoices) {
                //     return !in_array($inv->document_number, $wentOutInvoices);
                // });
                // $pendingInvoices = $invoices->filter(function ($inv) use ($wentOutInvoices) {
                //     return !in_array(strtoupper(trim($inv->document_number)), $wentOutInvoices);
                // });

                $pendingInvoices = $invoices->filter(function ($inv) use ($wentOutInvoices) {
                    $doc = preg_replace('/\s+/', '', strtoupper((string) $inv->document_number));

                    return ! in_array($doc, $wentOutInvoices, true);
                });

                if ($pendingInvoices->isEmpty()) {
                    continue;
                }

                foreach ($pendingInvoices as $inv) {
                    $yesterday = now()->subDay()->toDateString();
                    $today = now()->toDateString();
                    $documentDate = \Carbon\Carbon::parse($inv->document_date);

                    if (in_array($documentDate->toDateString(), [$today, $yesterday])) {
                        $statusColor = 'status-pending-yellow';
                    } else {
                        $statusColor = 'status-pending-red';
                    }

                    $tableData[] = [
                        // 'no' => $no++,
                        'plant' => $plant->name,
                        // 'distribution_type' => $selectedDistribution,
                        'customer_code' => $inv->customer_code,
                        'document_number' => $inv->document_number,
                        'document_date' => $inv->document_date,
                        'customer_trade_name' => $inv->customer_trade_name,
                        'customer_location' => $inv->customer_location,
                        'location' => $inv->location,
                        'no_of_days_pending' => abs((int) now()->diffInDays($documentDate)),
                        'status' => 'Pending',
                        'status_class' => $statusColor,
                    ];
                }
            }

            $tableData = collect($tableData)
                ->sortBy('document_date')
                ->values()
                ->map(function ($item, $index) {
                    $item['no'] = $index + 1;

                    return $item;
                })
                ->toArray();

            $mailSubject = "Despatch Pending Sale Invoice & STO Invoice as on Date ({$plant->name})";

            $mail = new InvoiceDataMail($scheduleType, $tableData, $mailSubject);
            $contentVars = $mail->content()->with;

            $this->info($contentVars['greeting'] ?? 'Invoice Data Report');
            $this->table(
                ['No', 'Plant', 'Customer Code', 'Document Number', 'Document Date', 'Trade Name', 'Location', 'Pending Days', 'Status'],// 'Distribution Type'
                $tableData
            );
            $this->info($contentVars['wishes'] ?? '');

            foreach ($mailRules as $rule) {
                $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 ID {$rule->id} — no valid To emails found.");

                    continue;
                }

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

                $this->info("Mail sent for rule ID {$rule->id} → To: ".implode(', ', $toEmails).($ccEmails ? ' | CC: '.implode(', ', $ccEmails) : ''));
            }
        }
    }
}
