<?php

namespace App\Console\Commands;

use App\Models\Contract;
use App\Services\ContractService;
use App\Services\InvoiceMailService;
use App\Services\Minimax\MinimaxInvoiceService;
use App\Services\PdfCacheService;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;

class SendInvoicesToMail extends Command
{
    protected $signature = 'inoffice:SendInvoicesToMail
                            {--month= : Month to send invoices for (format: YYYY-MM, default: current month)}
                            {--test : Send to test address only}';

    protected $description = 'Send invoices via email to contract recipients for a given month.';

    public function __construct(
        private ContractService $contractService,
        private MinimaxInvoiceService $invoiceService,
        private InvoiceMailService $mailService,
        private PdfCacheService $pdfCache,
    ) {
        parent::__construct();
    }

    public function handle(): int
    {
        $month    = $this->option('month') ?? Carbon::today()->format('Y-m');
        $testMode = (bool) $this->option('test');

        if ($testMode) {
            $this->warn('[TEST MODE] Emails will be sent to test address only.');
        }

        $this->info("Sending invoices for month: {$month}");

        // Load cached invoice list for the month
        $cachedInvoices = $this->pdfCache->load($month);

        if (empty($cachedInvoices)) {
            $this->error("No cached invoice data found for {$month}. Run inoffice:downloadInvoicesPdf first.");
            return self::FAILURE;
        }

        $this->info("Found " . count($cachedInvoices) . " cached invoice(s).");

        $sent   = 0;
        $errors = [];

        foreach ($cachedInvoices as $cached) {
            $invoiceId = $cached['id'] ?? null;
            $account   = $cached['account'] ?? null;

            if (!$invoiceId || !$account) {
                $this->warn("Skipping entry with missing id or account.");
                continue;
            }

            try {
                // Fetch full invoice data from Minimax to get contract reference
                $invoiceData = $this->invoiceService->getIssuedInvoiceAllData($account, (int) $invoiceId);

                // Determine contract_no from invoice payment reference or notes
                $contractNo = $invoiceData['PaymentReference']
                    ?? $invoiceData['Notes']
                    ?? null;

                if (!$contractNo) {
                    $this->warn("Invoice #{$invoiceId}: cannot determine contract_no — skipping.");
                    continue;
                }

                // Find matching contract
                $contract = Contract::where('contract_no', $contractNo)->first();

                if (!$contract) {
                    $this->warn("Invoice #{$invoiceId}: contract '{$contractNo}' not found — skipping.");
                    continue;
                }

                // Load PDF from storage if available
                $pdfContent = null;
                $pdfPath    = $cached['pdf_path'] ?? null;

                if ($pdfPath && Storage::exists($pdfPath)) {
                    $pdfContent = Storage::get($pdfPath);
                } else {
                    // Fetch PDF from Minimax
                    $pdfContent = $this->invoiceService->getDocumentAttachment($account, (int) $invoiceId, 'pdf');
                }

                // Fetch XML if eracun/send_xml enabled
                $xmlContent = null;
                if ($contract->eracun || $contract->send_xml) {
                    try {
                        $xmlContent = $this->invoiceService->getDocumentAttachment($account, (int) $invoiceId, 'xml');
                    } catch (\Throwable $e) {
                        $this->warn("Could not fetch XML for invoice #{$invoiceId}: " . $e->getMessage());
                    }
                }

                $this->mailService->sendInvoice(
                    $contract,
                    $invoiceData,
                    $pdfContent,
                    $xmlContent,
                    $testMode,
                    $account,
                );

                $this->line("  Sent invoice #{$invoiceId} for {$contract->customer_name}");
                $sent++;

            } catch (\Throwable $e) {
                $msg = $e->getMessage();
                $this->error("  ERROR for invoice #{$invoiceId}: {$msg}");
                Log::error("SendInvoicesToMail: #{$invoiceId}", ['error' => $msg]);
                $errors[] = ['id' => $invoiceId, 'message' => $msg];
            }
        }

        $this->info("Done. Sent: {$sent}, Errors: " . count($errors));

        return count($errors) > 0 ? self::FAILURE : self::SUCCESS;
    }
}
