<?php

namespace Modules\Sale\Controllers;

use App\Controllers\BaseController;
use App\Models\CompanyModel;
use App\Models\CustomerGroupModel;
use App\Models\LeadSourceModel;
use App\Models\SalesRepresentativeModel;
use App\Traits\ExportsReport;
use Modules\Sale\Services\SaleReportService;

class SaleReportController extends BaseController
{
    use ExportsReport;

    protected SaleReportService $reports;
    protected CompanyModel $companies;
    protected SalesRepresentativeModel $reps;
    protected CustomerGroupModel $groups;
    protected LeadSourceModel $sources;

    public function initController(\CodeIgniter\HTTP\RequestInterface $request, \CodeIgniter\HTTP\ResponseInterface $response, \Psr\Log\LoggerInterface $logger)
    {
        parent::initController($request, $response, $logger);
        $this->reports   = new SaleReportService();
        $this->companies = new CompanyModel();
        $this->reps      = new SalesRepresentativeModel();
        $this->groups    = new CustomerGroupModel();
        $this->sources   = new LeadSourceModel();
    }

    public function salesPerformance()
    {
        $filters = $this->reports->resolveFilters($this->request->getGet());
        $data    = $this->reports->salesPerformance($filters);

        if ($export = $this->exportSections(
            'sales_performance',
            'Sales Performance',
            [
                [
                    'title'   => 'Target Attainment',
                    'headers' => ['Representative', 'Territory', 'Period Start', 'Period End', 'Target', 'Achieved', 'Attainment %', 'Status'],
                    'rows'    => array_map(static fn ($row) => [
                        $row['rep_name'] ?? '',
                        $row['territory_name'] ?? '',
                        $row['period_start'] ?? '',
                        $row['period_end'] ?? '',
                        number_format((float) ($row['target_amount'] ?? 0), 2),
                        number_format((float) ($row['achieved_amount'] ?? 0), 2),
                        number_format((float) ($row['attainment_pct'] ?? 0), 1),
                        $row['status'] ?? '',
                    ], $data['targets'] ?? []),
                ],
                [
                    'title'   => 'Commission Summary',
                    'headers' => ['Status', 'Count', 'Amount'],
                    'rows'    => array_map(static fn ($row) => [
                        $row['status'] ?? '',
                        (int) ($row['total'] ?? 0),
                        number_format((float) ($row['amount'] ?? 0), 2),
                    ], $data['commissions']['byStatus'] ?? []),
                ],
            ],
            $filters['date_from'] . ' to ' . $filters['date_to']
        )) {
            return $export;
        }

        return view('Modules\Sale\Views\reports\sales_performance', array_merge($this->baseViewData(), $this->filterOptions(), [
            'title'      => 'Sales Performance',
            'filters'    => $filters,
            'report'     => $data,
            'loadCharts' => true,
        ]));
    }

    public function leadConversion()
    {
        $filters = $this->reports->resolveFilters($this->request->getGet());
        $data    = $this->reports->leadConversion($filters);

        if ($export = $this->exportSections(
            'lead_conversion',
            'Lead Conversion',
            [
                [
                    'title'   => 'By Source',
                    'headers' => ['Source', 'Leads', 'Converted', 'Rate %', 'Est. Value'],
                    'rows'    => array_map(static fn ($row) => [
                        $row['label'] ?? '',
                        (int) ($row['total'] ?? 0),
                        (int) ($row['converted'] ?? 0),
                        number_format((float) ($row['conversion_rate'] ?? 0), 1),
                        number_format((float) ($row['estimated_value'] ?? 0), 2),
                    ], $data['bySource'] ?? []),
                ],
                [
                    'title'   => 'By Assignee',
                    'headers' => ['Assignee', 'Leads', 'Converted', 'Rate %'],
                    'rows'    => array_map(static fn ($row) => [
                        $row['label'] ?? '',
                        (int) ($row['total'] ?? 0),
                        (int) ($row['converted'] ?? 0),
                        number_format((float) ($row['conversion_rate'] ?? 0), 1),
                    ], $data['byAssignee'] ?? []),
                ],
                [
                    'title'   => 'Recent Conversions',
                    'headers' => ['Lead', 'Company', 'Source', 'Type', 'Converted By', 'Est. Value', 'Converted At'],
                    'rows'    => array_map(static fn ($row) => [
                        trim(($row['first_name'] ?? '') . ' ' . ($row['last_name'] ?? '')),
                        $row['company_name'] ?? '',
                        $row['source_name'] ?? '',
                        $row['conversion_type'] ?? '',
                        $row['converted_by_name'] ?? '',
                        number_format((float) ($row['estimated_value'] ?? 0), 2),
                        $row['converted_at'] ?? '',
                    ], $data['recent'] ?? []),
                ],
            ],
            $filters['date_from'] . ' to ' . $filters['date_to']
        )) {
            return $export;
        }

        return view('Modules\Sale\Views\reports\lead_conversion', array_merge($this->baseViewData(), $this->filterOptions(), [
            'title'      => 'Lead Conversion',
            'filters'    => $filters,
            'report'     => $data,
            'loadCharts' => true,
        ]));
    }

    public function revenueForecast()
    {
        $filters = $this->reports->resolveFilters($this->request->getGet());
        $data    = $this->reports->revenueForecast($filters);

        if ($export = $this->exportTable(
            'revenue_forecast',
            'Revenue Forecast',
            ['Opportunity', 'Company', 'Stage', 'Expected', 'Probability %', 'Weighted', 'Close Date'],
            array_map(static fn ($row) => [
                $row['name'] ?? '',
                $row['company_name'] ?? '',
                $row['stage_name'] ?? '',
                number_format((float) ($row['expected_revenue'] ?? 0), 2),
                (int) ($row['probability'] ?? 0),
                number_format((float) ($row['weighted_revenue'] ?? 0), 2),
                $row['expected_close_date'] ?? '',
            ], $data['rows'] ?? []),
            $filters['date_from'] . ' to ' . $filters['date_to']
        )) {
            return $export;
        }

        return view('Modules\Sale\Views\reports\revenue_forecast', array_merge($this->baseViewData(), $this->filterOptions(), [
            'title'      => 'Revenue Forecast',
            'filters'    => $filters,
            'report'     => $data,
            'loadCharts' => true,
        ]));
    }

    public function customerAnalysis()
    {
        $filters = $this->reports->resolveFilters($this->request->getGet());
        $data    = $this->reports->customerAnalysis($filters);

        if ($export = $this->exportSections(
            'customer_analysis',
            'Customer Analysis',
            [
                [
                    'title'   => 'Top Customers',
                    'headers' => ['Company', 'Group', 'Invoices', 'Revenue', 'Paid', 'Outstanding'],
                    'rows'    => array_map(static function ($row) {
                        $revenue = (float) ($row['revenue'] ?? 0);
                        $paid    = (float) ($row['paid'] ?? 0);

                        return [
                            $row['company_name'] ?? '',
                            $row['group_name'] ?? '',
                            (int) ($row['invoice_count'] ?? 0),
                            number_format($revenue, 2),
                            number_format($paid, 2),
                            number_format(max(0, $revenue - $paid), 2),
                        ];
                    }, $data['topCustomers'] ?? []),
                ],
                [
                    'title'   => 'Outstanding',
                    'headers' => ['Company', 'Invoices', 'Balance'],
                    'rows'    => array_map(static fn ($row) => [
                        $row['company_name'] ?? '',
                        (int) ($row['invoice_count'] ?? 0),
                        number_format((float) ($row['balance'] ?? 0), 2),
                    ], $data['outstanding'] ?? []),
                ],
                [
                    'title'   => 'Activity',
                    'headers' => ['Company', 'Type', 'Count'],
                    'rows'    => array_map(static fn ($row) => [
                        $row['company_name'] ?? '',
                        $row['activity_type'] ?? '',
                        (int) ($row['total'] ?? 0),
                    ], $data['activity'] ?? []),
                ],
            ],
            $filters['date_from'] . ' to ' . $filters['date_to']
        )) {
            return $export;
        }

        return view('Modules\Sale\Views\reports\customer_analysis', array_merge($this->baseViewData(), $this->filterOptions(), [
            'title'      => 'Customer Analysis',
            'filters'    => $filters,
            'report'     => $data,
            'loadCharts' => true,
        ]));
    }

    public function salesReports()
    {
        $filters = $this->reports->resolveFilters($this->request->getGet());
        $data    = $this->reports->salesReports($filters);

        $agingHeaders = array_keys($data['aging'] ?? []);
        $agingHeaders[] = 'Total';
        $agingValues = [];
        $agingTotal = 0.0;
        foreach ($data['aging'] ?? [] as $amount) {
            $agingTotal += (float) $amount;
            $agingValues[] = number_format((float) $amount, 2);
        }
        $agingValues[] = number_format($agingTotal, 2);

        $sections = [[
            'title'   => 'Receivables Aging',
            'headers' => $agingHeaders,
            'rows'    => [$agingValues],
        ]];

        foreach ($data['sections'] ?? [] as $section) {
            $sections[] = [
                'title'   => $section['label'] ?? 'Section',
                'headers' => ['Status', 'Count'],
                'rows'    => array_map(static fn ($row) => [
                    ucwords(str_replace('_', ' ', (string) ($row['status'] ?? ''))),
                    (int) ($row['total'] ?? 0),
                ], $section['mix']['rows'] ?? []),
            ];
        }

        if ($export = $this->exportSections(
            'sales_reports',
            'Sales Reports',
            $sections,
            $filters['date_from'] . ' to ' . $filters['date_to']
        )) {
            return $export;
        }

        return view('Modules\Sale\Views\reports\sales_reports', array_merge($this->baseViewData(), $this->filterOptions(), [
            'title'      => 'Sales Reports',
            'filters'    => $filters,
            'report'     => $data,
            'loadCharts' => true,
        ]));
    }

    private function filterOptions(): array
    {
        return [
            'companies' => $this->companies->getActive(),
            'reps'      => $this->reps->getActive(),
            'groups'    => $this->groups->getActive(),
            'sources'   => $this->sources->getActive(),
        ];
    }
}
