<?php

namespace App\Console\Commands;

use App\Models\Setting;
use App\Models\Ticket;
use App\Services\TicketNotificationService;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class ProcessTicketAutoClose extends Command
{
    protected $signature = 'tickets:process-auto-close';

    protected $description = 'Send customer inactivity reminders and auto-close stale answered tickets.';

    public function handle(): int
    {
        if (Setting::get('tickets_auto_close_enabled', '1') !== '1') {
            $this->info('Ticket auto-close is disabled.');
            return self::SUCCESS;
        }

        /** @var TicketNotificationService $ticketNotificationService */
        $ticketNotificationService = app(TicketNotificationService::class);

        $timeoutDays = max(1, (int) Setting::get('tickets_customer_reply_timeout_days', '3'));
        $graceDays = max(1, (int) Setting::get('tickets_auto_close_grace_days', '1'));

        $this->processReminders($timeoutDays, $ticketNotificationService);
        $this->processAutoClose($graceDays, $ticketNotificationService);

        return self::SUCCESS;
    }

    private function processReminders(int $timeoutDays, TicketNotificationService $ticketNotificationService): void
    {
        $cutoff = now()->subDays($timeoutDays);

        Ticket::query()
            ->where('status', Ticket::STATUS_ANSWERED)
            ->whereNotNull('last_reply_at')
            ->whereNull('customer_reminder_sent_at')
            ->where('last_reply_at', '<=', $cutoff)
            ->orderBy('id')
            ->chunkById(100, function ($tickets) use ($ticketNotificationService) {
                foreach ($tickets as $ticket) {
                    DB::transaction(function () use ($ticket, $ticketNotificationService) {
                        $updatedRows = Ticket::query()
                            ->whereKey($ticket->id)
                            ->where('status', Ticket::STATUS_ANSWERED)
                            ->whereNull('customer_reminder_sent_at')
                            ->update([
                                'customer_reminder_sent_at' => now(),
                                'updated_at' => now(),
                            ]);

                        if ($updatedRows === 0) {
                            return;
                        }

                        $freshTicket = Ticket::with(['customer', 'order'])->find($ticket->id);
                        if (!$freshTicket) {
                            return;
                        }

                        $ticketNotificationService->notifyCustomerForInactivityReminder($freshTicket);
                    });
                }
            });
    }

    private function processAutoClose(int $graceDays, TicketNotificationService $ticketNotificationService): void
    {
        $cutoff = now()->subDays($graceDays);

        Ticket::query()
            ->where('status', Ticket::STATUS_ANSWERED)
            ->whereNotNull('customer_reminder_sent_at')
            ->where('customer_reminder_sent_at', '<=', $cutoff)
            ->orderBy('id')
            ->chunkById(100, function ($tickets) use ($ticketNotificationService) {
                foreach ($tickets as $ticket) {
                    DB::transaction(function () use ($ticket, $ticketNotificationService) {
                        $updatedRows = Ticket::query()
                            ->whereKey($ticket->id)
                            ->where('status', Ticket::STATUS_ANSWERED)
                            ->whereNotNull('customer_reminder_sent_at')
                            ->update([
                                'status' => Ticket::STATUS_CLOSED_BY_CUSTOMER,
                                'closed_at' => now(),
                                'auto_closed_at' => now(),
                                'auto_close_reason' => 'no_customer_reply_timeout',
                                'active_ticket_key' => null,
                                'updated_at' => now(),
                            ]);

                        if ($updatedRows === 0) {
                            return;
                        }

                        $freshTicket = Ticket::with(['customer', 'order'])->find($ticket->id);
                        if (!$freshTicket) {
                            return;
                        }

                        $ticketNotificationService->notifyCustomerForAutoClose($freshTicket);
                    });
                }
            });
    }
}

