<?php

namespace App\Console\Commands;

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

class GenerateActiveContractInvoices extends Command
{
    protected $signature = 'inoffice:generateActiveContractInvoices
                            {--account= : Minimax account key (default: all)}
                            {--contract= : Contract number to process (default: all eligible)}
                            {--dry-run : Simulate without creating invoices}';

    protected $description = 'Generate Minimax invoices for all active contracts eligible for invoicing.';

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

    public function handle(): int
    {
        $account   = $this->option('account');
        $contractNo = $this->option('contract');
        $dryRun    = (bool) $this->option('dry-run');

        if ($dryRun) {
            $this->warn('[DRY RUN] No invoices will actually be created.');
        }

        // Get eligible contracts
        $contracts = $this->contractService->getContractsToInvoice($account);

        // Filter by specific contract number if provided
        if ($contractNo) {
            $contracts = $contracts->filter(fn(Contract $c) => $c->contract_no === $contractNo)->values();
        }

        if ($contracts->isEmpty()) {
            $this->info('No contracts eligible for invoicing.');
            return self::SUCCESS;
        }

        $this->info("Processing {$contracts->count()} contract(s)...");

        $generated = 0;
        $errors    = [];
        $createdInvoices = [];

        foreach ($contracts as $contract) {
            $acc = $contract->minimax_account ?? $account;

            if (!$acc) {
                $this->warn("Contract {$contract->contract_no} has no minimax_account — skipping.");
                $errors[] = ['contract_no' => $contract->contract_no, 'message' => 'No minimax_account set'];
                continue;
            }

            try {
                $invoiceData = $this->invoiceService->buildInvoiceFromContract($acc, $contract);

                if ($dryRun) {
                    $this->line("  [DRY] Would create invoice for: {$contract->customer_name} ({$contract->contract_no})");
                    $generated++;
                    continue;
                }

                $result = $this->invoiceService->addIssuedInvoice($acc, $invoiceData);

                $invoiceNo = $result['InvoiceNumber'] ?? $result['IssuedInvoiceId'] ?? '?';
                $price = $contract->payment === 'month' ? $contract->price_per_month : $contract->price_per_year;

                $this->line("  Created invoice #{$invoiceNo} for {$contract->customer_name} ({$contract->contract_no})");
                $generated++;

                $createdInvoices[] = [
                    'customer_name' => $contract->customer_name,
                    'contract_no' => $contract->contract_no,
                    'invoice_number' => $invoiceNo,
                    'amount' => $price,
                    'website' => $contract->website,
                    'payment' => $contract->payment,
                ];

            } catch (\Throwable $e) {
                $msg = $e->getMessage();
                $this->error("  ERROR for {$contract->contract_no}: {$msg}");
                Log::error("GenerateActiveContractInvoices: {$contract->contract_no}", ['error' => $msg]);
                $errors[] = ['contract_no' => $contract->contract_no, 'message' => $msg];
            }
        }

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

        // Send notification email if admin address is configured
        $adminEmail = env('ADMIN_EMAIL');
        if ($adminEmail && !$dryRun) {
            try {
                Mail::send(
                    'emails.issuedInvoices',
                    [
                        'account'   => $account,
                        'total'     => $contracts->count(),
                        'generated' => $generated,
                        'errors'    => $errors,
                        'invoices'  => $createdInvoices,
                    ],
                    fn($m) => $m->to($adminEmail)->subject('InOffice — generiranje računa završeno')
                );
            } catch (\Throwable $e) {
                $this->warn("Could not send notification email: " . $e->getMessage());
            }
        }

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