<?php

namespace App\Console\Commands;

use App\Mail\CharacteristicApprovalMail;
use App\Models\CharacteristicApproverMaster;
use App\Models\RequestCharacteristic;
use App\Models\TempClassCharacteristic;
// use App\Models\TempClassCharacteristic;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Schema;

class TriggerPendingApprovalMails extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    // protected $signature = 'app:trigger-pending-approval-mails';

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

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

    protected $signature = 'approval:trigger-mails';
    protected $description = 'Trigger approval mail manually';

    public $pdfPath;

    public $subjectLine;

    // public $tempCharacteristics = [];

    public $wfId;

    public function handle()
    {
        $this->info('Approval mail job started');

        // .. Characteristic Mail trigger logic

        // $records = RequestCharacteristic::whereNull('approver_status1')
        // ->whereNull('approver_status2')
        // ->whereNull('approver_status3')
        // ->get();

        $records = RequestCharacteristic::where(function ($q) {
                $q->whereNull('approver_status1')
                ->orWhere('approver_status1', 'Hold');
            })
            ->where(function ($q) {
                $q->whereNull('approver_status2')
                ->orWhere('approver_status2', 'Hold');
            })
            ->where(function ($q) {
                $q->whereNull('approver_status3')
                ->orWhere('approver_status3', 'Hold');
            })
            ->get();

        $records = $records->filter(function ($item) {
            $approver = CharacteristicApproverMaster::find($item->characteristic_approver_master_id);
            return $approver && $approver->approver_type == 'Characteristic';
        });

        if ($records->isEmpty()) {
            $this->info('No characteristics pending approvals');
        }else{
            $grouped = $records->groupBy(function ($item) {
                $this->wfId = $item->work_flow_id;
                return $item->plant_id . '|' . $item->machine_id . '|' . $item->aufnr . '|' . $item->work_flow_id;
            });

            $pendingApprovers = RequestCharacteristic::where('work_flow_id', $this->wfId)->latest()->first();

            $this->info($pendingApprovers->approver_status1, $pendingApprovers->approver_status2);


            $approverNameFromMaster = null;
            if ($pendingApprovers && $pendingApprovers->characteristic_approver_master_id) {
                $approverNameFromMaster = CharacteristicApproverMaster::find($pendingApprovers->characteristic_approver_master_id);
            }

            $rows = [];

            foreach ($grouped as $groupRecords) {

                $first = $groupRecords->first();

                $approver = CharacteristicApproverMaster::where('plant_id', $first->plant_id)
                    ->where('machine_id', $first->machine_id)
                    ->where('id', $first->characteristic_approver_master_id)
                    ->first();

                if (!$approver) {
                    continue;
                }

                $characteristics = $groupRecords->map(fn ($r) => [
                    'work_flow_id'        => $r->work_flow_id,
                    'characteristic_name' => $r->characteristic_name,
                    'current_value'       => $r->current_value,
                    'update_value'        => $r->update_value,
                ])->toArray();

                $level    = null;
                $mail     = null;
                $name     = null;
                $updateData = [];
                $now = Carbon::now();

                // --- FIRST MAIL ---
                if (is_null($first->mail_status)){
                    $level = 1;
                    $mail = $approver->mail1;
                    $name = $approver->name1;

                    $updateData['mail_status'] = 'Sent';

                    if ($approver->duration1 > 0)
                    {

                        $duration = number_format((float)$approver->duration1, 2, '.', '');
                        [$hours, $minutes] = explode('.', $duration);

                        $totalMinutes = ((int)$hours * 60) + (int)$minutes;

                        $updateData['trigger_at'] = $now
                            ->copy()
                            ->addMinutes($totalMinutes)
                            ->startOfMinute();
                    }
                    else
                    {
                        $updateData['trigger_at'] = null;
                    }
                }

                // --- SECOND MAIL ---
                elseif (
                    $first->mail_status == 'Sent' &&
                    (is_null($first->approver_status1) || $first->approver_status1 == 'Hold') &&
                    $first->trigger_at &&
                    \Carbon\Carbon::parse($first->trigger_at)->lte($now)
                ) {

                    $this->info(
                        "mail_status: {$first->mail_status}, ".
                        "approver_status1: {$first->approver_status1}, ".
                        "trigger_at: {$first->trigger_at}, ".
                        "now: {$now}"
                    );

                    $level = 2;
                    $mail = $approver->mail2;
                    $name = $approver->name2;

                    if ($approver->duration2 > 0) {

                        $duration = number_format((float)$approver->duration2, 2, '.', '');
                        [$hours, $minutes] = explode('.', $duration);

                        $totalMinutes = ((int)$hours * 60) + (int)$minutes;

                        $updateData['trigger_at'] = $now->copy()->addMinutes($totalMinutes);
                    } else {
                        $updateData['trigger_at'] = null;
                    }

                    $updateData['mail_status'] = 'Sent-Mail2';
                }

                // --- THIRD MAIL ---
                elseif (
                    $first->mail_status == 'Sent-Mail2' &&
                    (is_null($first->approver_status1) || $first->approver_status1 == 'Hold') &&
                    (is_null($first->approver_status2) || $first->approver_status2 == 'Hold') &&
                    $first->trigger_at &&
                    \Carbon\Carbon::parse($first->trigger_at)->lte($now)
                ) {
                    $level = 3;
                    $mail = $approver->mail3;
                    $name = $approver->name3;

                    $updateData['trigger_at'] = null;
                    $updateData['mail_status'] = 'Sent-Mail3';
                }

                $totalMinutes =
                $this->convertToMinutes($approver->duration1 ?? 0) +
                $this->convertToMinutes($approver->duration2 ?? 0) +
                $this->convertToMinutes($approver->duration3 ?? 0);

                $expiryTime = Carbon::parse($first->created_at)
                    ->copy()
                    ->addMinutes($totalMinutes);

                $ids = $groupRecords->pluck('id');

                $this->info("Expiry Time for ID {$first->id}: {$expiryTime}, Now: {$now}");

                // --- AUTO REJECT ---
                if (
                    $first->mail_status == 'Sent-Mail3' &&
                    (is_null($first->approver_status1) || $first->approver_status1 == 'Hold') &&
                    (is_null($first->approver_status2) || $first->approver_status2 == 'Hold') &&
                    (is_null($first->approver_status3) || $first->approver_status3 == 'Hold') &&
                    $now->gte($expiryTime)
                ) {
                    RequestCharacteristic::whereIn('id', $ids)
                        ->update([
                            'approver_status3' => 'Rejected',
                            'approver_remark3' => 'Time Limit Reached',
                            'approved3_at' => now(),
                        ]);

                    $this->info("Auto Rejected ID: {$first->id}");
                    continue;
                }

                if (!$level || !$mail) {
                    continue;
                }

                $pdfPath = 'uploads/LaserDocs/' . $first->work_flow_id . '.pdf';

                $subjectLine = 'Characteristic Approval Mail';

                // $emails = array_map('trim', explode(',', $mail));

                Mail::to($mail)->send(
                    new CharacteristicApprovalMail(
                        $first,
                        $name,
                        $level,
                        $pdfPath,
                        $pendingApprovers,
                        $approverNameFromMaster,
                        $subjectLine,
                        $characteristics
                    )
                );

                RequestCharacteristic::whereIn('id', $groupRecords->pluck('id'))
                    ->update($updateData);

                $rows[] = [
                    $first->id,
                    $first->plant_id,
                    $first->machine_id,
                    "Level $level",
                    $mail,
                    'SENT'
                ];
            }
        }

        // .. Quality Mail trigger logic

        $qualityRecords = RequestCharacteristic::where(function ($q) {
                $q->whereNull('approver_status1')
                ->orWhere('approver_status1', 'Hold');
            })
            ->where(function ($q) {
                $q->whereNull('approver_status2')
                ->orWhere('approver_status2', 'Hold');
            })
            ->where(function ($q) {
                $q->whereNull('approver_status3')
                ->orWhere('approver_status3', 'Hold');
            })
            ->get();

        $qualityRecords = $qualityRecords->filter(function ($item) {
            $approver = CharacteristicApproverMaster::find($item->characteristic_approver_master_id);
            return $approver && $approver->approver_type == 'Quality';
        });

        // $approvers = CharacteristicApproverMaster::where('approver_type', 'Quality')
        //     ->get()
        //     ->keyBy('id');

        // $qualityRecords = RequestCharacteristic::where(function ($q) {
        //         $q->whereNull('approver_status1')->orWhere('approver_status1', 'Hold');
        //     })
        //     ->where(function ($q) {
        //         $q->whereNull('approver_status2')->orWhere('approver_status2', 'Hold');
        //     })
        //     ->where(function ($q) {
        //         $q->whereNull('approver_status3')->orWhere('approver_status3', 'Hold');
        //     })
        //     ->whereIn('characteristic_approver_master_id', $approvers->keys())
        //     ->get();


        if ($qualityRecords->isEmpty()) {
            $this->info('No quality pending approvals');
            return;
        }

        $grouped = $qualityRecords->groupBy(function ($item) {
            $this->wfId = $item->work_flow_id;
            return $item->plant_id . '|' . $item->machine_id . '|' . $item->aufnr . '|' . $item->work_flow_id;
        });

        $pendingApprovers = RequestCharacteristic::where('work_flow_id', $this->wfId)->latest()->first();

        $approverNameFromMaster = null;
        if ($pendingApprovers && $pendingApprovers->characteristic_approver_master_id) {
            $approverNameFromMaster = CharacteristicApproverMaster::find($pendingApprovers->characteristic_approver_master_id);
        }

        $rows = [];

        foreach ($grouped as $groupRecords) {

            $first = $groupRecords->first();

            $approver = CharacteristicApproverMaster::where('plant_id', $first->plant_id)
                ->where('machine_id', $first->machine_id)
                ->where('id', $first->characteristic_approver_master_id)
                ->first();

            if (!$approver) {
                continue;
            }

            $columns = Schema::getColumnListing('temp_class_characteristics');

            $exclude = ['id', 'plant_id', 'machine_id', 'item_id', 'aufnr', 'class', 'arbid', 'gamng', 'lmnga', 'zz1_cn_bill_ord', 'zmm_heading', 'created_at', 'updated_at', 'deleted_at', 'has_work_flow_id', 'model_type', 'created_by', 'updated_by' ];

            $filteredColumns = array_diff($columns, $exclude);

            $row1 = TempClassCharacteristic::where('plant_id', $first->plant_id)
                ->where('machine_id', $first->machine_id)
                ->where('aufnr', $first->aufnr)
                ->where('model_type', $first->model_type)
                ->latest()
                ->first();

            $this->info(json_encode([
                'id' => $row1->id,
                'plant_id' => $row1->plant_id,
                'machine_id' => $row1->machine_id,
                'aufnr' => $row1->aufnr,
                'motor_speed' => $row1->zmm_motor_speed,
                'all_data' => $row1->toArray(),
            ]));

            $data = [];

            if ($row1) {
                foreach ($filteredColumns as $column) {

                    $value = $row1->getAttribute($column);

                    if ($value != null && $value != '') {
                        $data[$column] = $value;
                    }
                }
            }

            $characteristics = $data;

            $level    = null;
            $mail     = null;
            $name     = null;
            $updateData = [];
            $now = Carbon::now();

            // --- FIRST MAIL ---
            if (is_null($first->mail_status)){
                $level = 1;
                $mail = $approver->mail1;
                $name = $approver->name1;

                $updateData['mail_status'] = 'Sent';

                if ($approver->duration1 > 0)
                {

                    $duration = number_format((float)$approver->duration1, 2, '.', '');
                    [$hours, $minutes] = explode('.', $duration);

                    $totalMinutes = ((int)$hours * 60) + (int)$minutes;

                    $updateData['trigger_at'] = $now
                        ->copy()
                        ->addMinutes($totalMinutes)
                        ->startOfMinute();
                }
                else
                {
                    $updateData['trigger_at'] = null;
                }
            }

            // --- SECOND MAIL ---
            elseif (
                $first->mail_status == 'Sent' &&
                (is_null($first->approver_status1) || $first->approver_status1 == 'Hold') &&
                $first->trigger_at &&
                \Carbon\Carbon::parse($first->trigger_at)->lte($now)
            ) {
                $level = 2;
                $mail = $approver->mail2;
                $name = $approver->name2;

                if ($approver->duration2 > 0) {

                    $duration = number_format((float)$approver->duration2, 2, '.', '');
                    [$hours, $minutes] = explode('.', $duration);

                    $totalMinutes = ((int)$hours * 60) + (int)$minutes;

                    // IMPORTANT: use NOW, not old trigger
                    $updateData['trigger_at'] = $now->copy()->addMinutes($totalMinutes);
                } else {
                    $updateData['trigger_at'] = null;
                }

                $updateData['mail_status'] = 'Sent-Mail2';
            }

            // --- THIRD MAIL ---
            elseif (
                $first->mail_status == 'Sent-Mail2' &&
                (is_null($first->approver_status1) || $first->approver_status1 == 'Hold') &&
                (is_null($first->approver_status2) || $first->approver_status2 == 'Hold') &&
                $first->trigger_at &&
                \Carbon\Carbon::parse($first->trigger_at)->lte($now)
            ) {
                $level = 3;
                $mail = $approver->mail3;
                $name = $approver->name3;

                $updateData['trigger_at'] = null;
                $updateData['mail_status'] = 'Sent-Mail3';
            }

            $totalMinutes =
            $this->convertToMinutes($approver->duration1 ?? 0) +
            $this->convertToMinutes($approver->duration2 ?? 0) +
            $this->convertToMinutes($approver->duration3 ?? 0);

            $expiryTime = Carbon::parse($first->created_at)
                ->copy()
                ->addMinutes($totalMinutes);

            $ids = $groupRecords->pluck('id');

            $this->info("Expiry Time for ID {$first->id}: {$expiryTime}, Now: {$now}");

            // --- AUTO REJECT ---
            if (
                $first->mail_status == 'Sent-Mail3' &&
                (is_null($first->approver_status1) || $first->approver_status1 == 'Hold') &&
                (is_null($first->approver_status2) || $first->approver_status2 == 'Hold') &&
                (is_null($first->approver_status3) || $first->approver_status3 == 'Hold') &&
                $now->gte($expiryTime)
            ) {
                RequestCharacteristic::whereIn('id', $ids)
                    ->update([
                        'approver_status3' => 'Rejected',
                        'approver_remark3' => 'Time Limit Reached',
                        'approved3_at' => now(),
                    ]);

                $this->info("Auto Rejected ID: {$first->id}");
                continue;
            }

            if (!$level || !$mail) {
                continue;
            }

            $pdfPath = ($f = glob(storage_path('app/private/uploads/LaserDocs/' . $first->work_flow_id . '.*')))
                ? 'uploads/LaserDocs/' . basename($f[0])
                : null;

            $this->info( $pdfPath);

            $subjectLine = 'Quality Approval Mail';

            $emails = array_map('trim', explode(',', $mail));

            Mail::to($emails)->send(
                new CharacteristicApprovalMail(
                    $first,
                    $name,
                    $level,
                    $pdfPath,
                    $pendingApprovers,
                    $approverNameFromMaster,
                    $subjectLine,
                    $characteristics
                )
            );

            RequestCharacteristic::whereIn('id', $groupRecords->pluck('id'))
                ->update($updateData);

            $rows[] = [
                $first->id,
                $first->plant_id,
                $first->machine_id,
                "Level $level",
                $mail,
                'SENT'
            ];
        }

        $this->table(
            ['ID', 'Plant', 'Machine', 'Level', 'Mail', 'Status'],
            $rows
        );

        $this->info('Approval mail job completed');
    }

    public function convertToMinutes($duration)
    {
        if (!$duration) return 0;

        $parts = explode('.', (string)$duration);

        $hours = (int)($parts[0] ?? 0);
        $minutes = (int)($parts[1] ?? 0);

        return ($hours * 60) + $minutes;
    }
}
