<?php

namespace App\Services;

use App\Models\Invoice;
use App\Models\Bill;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;

class AIService
{
    /**
     * Audit Invoices for anomalies
     */
    public function auditInvoices()
    {
        $anomalies = [];

        // 1. Detect Potential Duplicates (Same Customer, Same Amount, Within 24 Hours)
        $recentInvoices = Invoice::where('created_at', '>=', Carbon::now()->subDays(30))->get();

        foreach ($recentInvoices as $invoice) {
            $duplicate = Invoice::where('customer_id', $invoice->customer_id)
                ->where('total', $invoice->total)
                ->where('id', '!=', $invoice->id)
                ->where('created_at', '>=', $invoice->created_at->subDay())
                ->where('created_at', '<=', $invoice->created_at->addDay())
                ->first();

            if ($duplicate) {
                // Avoid adding the pair twice
                $key = 'dup_inv_' . min($invoice->id, $duplicate->id) . '_' . max($invoice->id, $duplicate->id);
                if (!isset($anomalies[$key])) {
                    $anomalies[$key] = [
                        'type' => 'warning',
                        'message' => "Potential duplicate invoice detected: #{$invoice->code} and #{$duplicate->code} have the same amount ({$invoice->total}) for the same customer within 24 hours.",
                        'action_link' => route('accounting.invoices.show', $invoice->id),
                    ];
                }
            }
        }

        // 2. Detect Broken Sequence (Gaps in Invoice Numbers)
        // Assuming format INV-YYYY-0001
        // This is a simplified check for the last 50 invoices
        $codes = Invoice::latest()->take(50)->pluck('code')->toArray();
        // Parse ID from code
        $ids = [];
        foreach ($codes as $code) {
            if (preg_match('/INV-\d{4}-(\d+)/', $code, $matches)) {
                $ids[] = intval($matches[1]);
            }
        }
        sort($ids);

        if (count($ids) > 1) {
            for ($i = 0; $i < count($ids) - 1; $i++) {
                if ($ids[$i + 1] != $ids[$i] + 1) {
                    $missing = $ids[$i] + 1;
                    $anomalies['gap_inv_' . $missing] = [
                        'type' => 'danger',
                        'message' => "Gap in invoice sequence detected. Invoice ending in " . str_pad($missing, 4, '0', STR_PAD_LEFT) . " appears to be missing.",
                        'action_link' => route('accounting.invoices.index'),
                    ];
                }
            }
        }

        return array_values($anomalies);
    }

    /**
     * Audit Expenses/Bills for anomalies
     */
    public function auditExpenses()
    {
        $anomalies = [];

        // Detect Duplicate Bills (Same Supplier, Same Amount, Same Reference)
        $bills = Bill::where('created_at', '>=', Carbon::now()->subDays(30))->get();

        foreach ($bills as $bill) {
            $duplicate = Bill::where('supplier_id', $bill->supplier_id)
                ->where('amount', $bill->amount)
                ->where('id', '!=', $bill->id)
                ->first();

            if ($duplicate) {
                $key = 'dup_bill_' . min($bill->id, $duplicate->id);
                if (!isset($anomalies[$key])) {
                    $supplierName = $bill->supplier->name ?? 'Unknown';
                    $anomalies[$key] = [
                        'type' => 'warning',
                        'message' => "Potential duplicate bill detected from supplier {$supplierName} with amount {$bill->amount}.",
                        'action_link' => route('accounting.bills.show', $bill->id),
                    ];
                }
            }
        }

        return array_values($anomalies);
    }

    /**
     * Get aggregated insights
     */
    public function getInsights()
    {
        $invoiceAnomalies = $this->auditInvoices();
        $expenseAnomalies = $this->auditExpenses();

        return array_merge($invoiceAnomalies, $expenseAnomalies);
    }
}
