<?php

namespace App\Controllers\View;

use App\Controllers\BaseController;
use App\Libraries\Tuition\TuitionForecastService;

class TuitionForecastController extends BaseController
{
    protected TuitionForecastService $forecastService;

    public function __construct()
    {
        $this->forecastService = new TuitionForecastService();
        helper(['url']);
    }

    public function index()
    {
        $schoolYear = trim((string) ($this->request->getGet('school_year') ?? ''));
        $semester = trim((string) ($this->request->getGet('semester') ?? ''));
        $mode = (string) ($this->request->getGet('calculator_mode') ?? 'compare');
        $filters = $this->buildOptionsFromRequest('get');
        $result = $this->forecastService->calculate($schoolYear, $semester, $mode, $filters);

        return view('administrator/tuition_forecast', [
            'title' => 'Tuition Collection Forecast',
            'schoolYears' => $this->forecastService->getAvailableSchoolYears(),
            'semesters' => $this->forecastService->getAvailableSemesters(),
            'filters' => [
                'school_year' => $result['school_year'],
                'semester' => $result['semester'],
                'calculator_mode' => $result['calculator_mode'],
            ] + $result['options'],
            'result' => $result,
        ]);
    }

    public function calculate()
    {
        $schoolYear = trim((string) ($this->request->getPost('school_year') ?? ''));
        $semester = trim((string) ($this->request->getPost('semester') ?? ''));
        $mode = (string) ($this->request->getPost('calculator_mode') ?? 'compare');

        return $this->response->setJSON(
            $this->forecastService->calculate($schoolYear, $semester, $mode, $this->buildOptionsFromRequest('post'))
        );
    }

    public function exportCsv()
    {
        $schoolYear = trim((string) ($this->request->getGet('school_year') ?? ''));
        $semester = trim((string) ($this->request->getGet('semester') ?? ''));
        $mode = (string) ($this->request->getGet('calculator_mode') ?? 'compare');
        $result = $this->forecastService->calculate($schoolYear, $semester, $mode, $this->buildOptionsFromRequest('get'));

        $filename = sprintf(
            'tuition_forecast_%s_%s_%s.csv',
            preg_replace('/[^A-Za-z0-9_-]+/', '-', $result['school_year']) ?: 'school-year',
            preg_replace('/[^A-Za-z0-9_-]+/', '-', $result['semester']) ?: 'all-year',
            $result['calculator_mode']
        );

        $handle = fopen('php://temp', 'w+');
        if ($handle === false) {
            throw new \RuntimeException('Unable to create CSV export.');
        }

        fputcsv($handle, ['School Year', $result['school_year']]);
        fputcsv($handle, ['Semester', $result['semester'] !== '' ? $result['semester'] : 'All Year']);
        fputcsv($handle, ['Calculator Mode', $result['calculator_mode']]);
        fputcsv($handle, []);
        fputcsv($handle, ['Summary']);
        fputcsv($handle, ['Families', 'Students', 'Billable Students', 'Grade Unit Price', 'Youth Unit Price', 'Old Projected Income', 'New Projected Income', 'Difference']);
        fputcsv($handle, [
            $result['summary']['family_count'],
            $result['summary']['student_count'],
            $result['summary']['billable_student_count'],
            $result['summary']['unit_price'],
            $result['summary']['youth_unit_price'],
            $result['summary']['old_projected_income'] ?? $result['summary']['old_projected_tuition'],
            $result['summary']['new_projected_income'] ?? $result['summary']['new_projected_tuition'],
            $result['summary']['difference'],
        ]);
        fputcsv($handle, []);
        fputcsv($handle, ['Families']);
        fputcsv($handle, ['Parent/Family', 'Student Count', 'Billable Student Count', 'Old Tuition Total', 'New Tuition Total', 'Difference', 'Warnings']);

        foreach ($result['families'] as $family) {
            fputcsv($handle, [
                $family['parent_name'] ?? '',
                $family['student_count'] ?? 0,
                $family['billable_student_count'] ?? 0,
                $family['old_total'] ?? '0.00',
                $family['new_total'] ?? '0.00',
                $family['difference'] ?? '0.00',
                implode(' | ', $family['warnings'] ?? []),
            ]);

            fputcsv($handle, ['Student Name', 'Grade', 'Billable', 'Excluded Reason', 'Old Rule', 'Old Amount', 'New Rule', 'New Amount']);
            foreach ($family['student_details'] as $detail) {
                fputcsv($handle, [
                    $detail['student_name'] ?? '',
                    $detail['grade_level'] ?? '',
                    !empty($detail['billable']) ? 'Yes' : 'No',
                    $detail['excluded_reason'] ?? '',
                    $detail['old_rule'] ?? '',
                    $detail['old_amount'] ?? '0.00',
                    $detail['new_rule'] ?? '',
                    $detail['new_amount'] ?? '0.00',
                ]);
            }
            fputcsv($handle, []);
        }

        rewind($handle);
        $csv = stream_get_contents($handle) ?: '';
        fclose($handle);

        return $this->response
            ->setHeader('Content-Type', 'text/csv; charset=UTF-8')
            ->setHeader('Content-Disposition', 'attachment; filename="' . $filename . '"')
            ->setBody($csv);
    }

    protected function buildOptionsFromRequest(string $method): array
    {
        $source = $method === 'post' ? 'getPost' : 'getGet';

        return [
            'include_withdrawn_mode' => (string) ($this->request->{$source}('include_withdrawn_mode') ?? 'refund_deadline'),
            'include_payment_pending' => $this->request->{$source}('include_payment_pending') ?? '0',
            'include_event_only' => $this->request->{$source}('include_event_only') ?? '0',
            'include_paid_invoices' => $this->request->{$source}('include_paid_invoices') ?? '0',
            'unit_price' => $this->request->{$source}('unit_price') ?? '',
            'youth_unit_price' => $this->request->{$source}('youth_unit_price') ?? '',
        ];
    }
}
