<?php
declare(strict_types=1);

namespace App\Modules\Procurement\Controllers;

use App\Core\Controller;
use App\Core\Request;
use App\Core\Response;
use App\Core\App;

class ProcurementReportController extends Controller
{
    public function purchaseVolume(Request $request): Response
    {
        $db = App::getInstance()->db();

        $dateFrom = trim((string) $request->get('date_from', date('Y-01-01')));
        $dateTo   = trim((string) $request->get('date_to', date('Y-m-d')));

        // Monthly purchase volume
        $monthly = $db->select(
            "SELECT DATE_FORMAT(`created_at`, '%Y-%m') as month,
                    COUNT(*) as order_count,
                    COALESCE(SUM(`total_amount`), 0) as total_value
             FROM `purchase_orders`
             WHERE `is_archived` = 0 AND `status` NOT IN ('cancelled')
               AND `created_at` >= ? AND `created_at` <= ?
             GROUP BY DATE_FORMAT(`created_at`, '%Y-%m')
             ORDER BY month ASC",
            [$dateFrom, $dateTo . ' 23:59:59']
        );

        // Top suppliers by value
        $topSuppliers = $db->select(
            "SELECT s.`name_ar`, COUNT(po.`id`) as order_count,
                    COALESCE(SUM(po.`total_amount`), 0) as total_value
             FROM `purchase_orders` po
             JOIN `suppliers` s ON s.`id` = po.`supplier_id`
             WHERE po.`is_archived` = 0 AND po.`status` NOT IN ('cancelled')
               AND po.`created_at` >= ? AND po.`created_at` <= ?
             GROUP BY po.`supplier_id`, s.`name_ar`
             ORDER BY total_value DESC LIMIT 10",
            [$dateFrom, $dateTo . ' 23:59:59']
        );

        // Top items by quantity
        $topItems = $db->select(
            "SELECT i.`name_ar`, i.`sku`,
                    COALESCE(SUM(poi.`quantity`), 0) as total_qty,
                    COALESCE(SUM(poi.`line_total`), 0) as total_value
             FROM `purchase_order_items` poi
             JOIN `inventory_items` i ON i.`id` = poi.`item_id`
             JOIN `purchase_orders` po ON po.`id` = poi.`purchase_order_id`
             WHERE po.`is_archived` = 0 AND po.`status` NOT IN ('cancelled')
               AND po.`created_at` >= ? AND po.`created_at` <= ?
             GROUP BY poi.`item_id`, i.`name_ar`, i.`sku`
             ORDER BY total_value DESC LIMIT 10",
            [$dateFrom, $dateTo . ' 23:59:59']
        );

        // Summary totals
        $totals = $db->selectOne(
            "SELECT COUNT(*) as total_orders,
                    COALESCE(SUM(`total_amount`), 0) as total_value
             FROM `purchase_orders`
             WHERE `is_archived` = 0 AND `status` NOT IN ('cancelled')
               AND `created_at` >= ? AND `created_at` <= ?",
            [$dateFrom, $dateTo . ' 23:59:59']
        );

        return $this->view('Procurement.Views.reports.purchase_volume', [
            'monthly'      => $monthly,
            'topSuppliers' => $topSuppliers,
            'topItems'     => $topItems,
            'totals'       => $totals,
            'filters'      => ['date_from' => $dateFrom, 'date_to' => $dateTo],
        ]);
    }

    public function supplierPerformance(Request $request): Response
    {
        $db = App::getInstance()->db();

        $suppliers = $db->select(
            "SELECT s.`id`, s.`code`, s.`name_ar`, s.`rating`,
                    s.`total_orders`, s.`on_time_delivery_count`, s.`quality_acceptance_count`,
                    s.`average_lead_days`, s.`last_order_date`,
                    COALESCE(ap_sum.outstanding, 0) as outstanding_balance
             FROM `suppliers` s
             LEFT JOIN (
                 SELECT `supplier_id`, SUM(`balance`) as outstanding
                 FROM `accounts_payable`
                 WHERE `is_archived` = 0 AND `status` IN ('pending', 'partial', 'overdue')
                 GROUP BY `supplier_id`
             ) ap_sum ON ap_sum.`supplier_id` = s.`id`
             WHERE s.`is_archived` = 0 AND s.`is_active` = 1
             ORDER BY s.`total_orders` DESC"
        );

        return $this->view('Procurement.Views.reports.supplier_performance', [
            'suppliers' => $suppliers,
        ]);
    }

    public function matchStatus(Request $request): Response
    {
        $db = App::getInstance()->db();

        $invoices = $db->select(
            "SELECT vi.`id`, vi.`internal_number`, vi.`invoice_number`, vi.`total_amount`,
                    vi.`status`, vi.`match_status`,
                    s.`name_ar` as supplier_name,
                    po.`po_number`
             FROM `vendor_invoices` vi
             JOIN `suppliers` s ON s.`id` = vi.`supplier_id`
             LEFT JOIN `purchase_orders` po ON po.`id` = vi.`purchase_order_id`
             WHERE vi.`is_archived` = 0
             ORDER BY
                CASE vi.`match_status`
                    WHEN 'discrepancy' THEN 1
                    WHEN 'tolerance_pass' THEN 2
                    WHEN 'unmatched' THEN 3
                    WHEN 'matched' THEN 4
                    ELSE 5
                END,
                vi.`created_at` DESC
             LIMIT 50"
        );

        // Summary counts
        $summary = $db->selectOne(
            "SELECT
                COUNT(*) as total,
                COUNT(CASE WHEN `match_status` = 'matched' THEN 1 END) as matched,
                COUNT(CASE WHEN `match_status` = 'discrepancy' THEN 1 END) as discrepancy,
                COUNT(CASE WHEN `match_status` = 'tolerance_pass' THEN 1 END) as tolerance_pass,
                COUNT(CASE WHEN `match_status` = 'unmatched' OR `match_status` IS NULL THEN 1 END) as unmatched
             FROM `vendor_invoices` WHERE `is_archived` = 0"
        );

        return $this->view('Procurement.Views.reports.match_status', [
            'invoices' => $invoices,
            'summary'  => $summary,
        ]);
    }

    public function overdueInvoices(Request $request): Response
    {
        $db = App::getInstance()->db();

        $overdue = $db->select(
            "SELECT ap.*, s.`name_ar` as supplier_name,
                    DATEDIFF(CURDATE(), ap.`due_date`) as days_overdue
             FROM `accounts_payable` ap
             JOIN `suppliers` s ON s.`id` = ap.`supplier_id`
             WHERE ap.`is_archived` = 0
               AND ap.`status` IN ('overdue', 'pending', 'partial')
               AND ap.`due_date` < CURDATE()
             ORDER BY ap.`due_date` ASC"
        );

        // Aging summary
        $aging = $db->selectOne(
            "SELECT
                COALESCE(SUM(CASE WHEN DATEDIFF(CURDATE(), `due_date`) BETWEEN 1 AND 30 THEN `balance` ELSE 0 END), 0) as days_1_30,
                COALESCE(SUM(CASE WHEN DATEDIFF(CURDATE(), `due_date`) BETWEEN 31 AND 60 THEN `balance` ELSE 0 END), 0) as days_31_60,
                COALESCE(SUM(CASE WHEN DATEDIFF(CURDATE(), `due_date`) BETWEEN 61 AND 90 THEN `balance` ELSE 0 END), 0) as days_61_90,
                COALESCE(SUM(CASE WHEN DATEDIFF(CURDATE(), `due_date`) > 90 THEN `balance` ELSE 0 END), 0) as over_90,
                COALESCE(SUM(`balance`), 0) as total_overdue
             FROM `accounts_payable`
             WHERE `is_archived` = 0 AND `due_date` < CURDATE() AND `status` IN ('overdue', 'pending', 'partial')"
        );

        return $this->view('Procurement.Views.reports.overdue_invoices', [
            'overdue' => $overdue,
            'aging'   => $aging,
        ]);
    }
}
