<?php

namespace App\Http\Controllers\Api;

use App\Exports\DuesCollectionExport;
use App\Exports\EventAttendeesExport;
use App\Exports\ExpenseSummaryExport;
use App\Exports\MemberListExport;
use App\Exports\OverdueMembersExport;
use App\Exports\PaymentHistoryExport;
use App\Services\ReportingService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Maatwebsite\Excel\Facades\Excel;

class ReportController extends BaseApiController
{
    public function __construct(
        private readonly ReportingService $reportingService
    ) {}

    // =========================================================================
    // Helper
    // =========================================================================

    private function getAssociationId(): ?int
    {
        $user = Auth::user();
        $association = $user?->associations()?->first();
        return $association?->id;
    }

    private function requireAssociation(): array
    {
        $associationId = $this->getAssociationId();
        if (!$associationId) {
            return [null, $this->error('No association found', null, 403)];
        }
        return [$associationId, null];
    }

    // =========================================================================
    // Member-Facing Endpoints (Transparency — NOT module-gated)
    // =========================================================================

    /**
     * Combined financial summary: revenue + expense overview + net position.
     */
    public function financialSummary(Request $request): JsonResponse
    {
        [$associationId, $errorResponse] = $this->requireAssociation();
        if ($errorResponse) return $errorResponse;

        $period = $request->input('period', '12_months');

        $revenue = $this->reportingService->getRevenueOverview($associationId, $period);
        $expenses = $this->reportingService->getExpenseOverview($associationId, $period);

        return $this->success([
            'revenue' => $revenue,
            'expenses' => $expenses,
        ], 'Financial summary retrieved');
    }

    /**
     * Monthly revenue trend data.
     */
    public function revenueTrend(Request $request): JsonResponse
    {
        [$associationId, $errorResponse] = $this->requireAssociation();
        if ($errorResponse) return $errorResponse;

        $period = $request->input('period', '12_months');
        $data = $this->reportingService->getRevenueTrend($associationId, $period);

        return $this->success($data, 'Revenue trend retrieved');
    }

    /**
     * Monthly expense trend data.
     */
    public function expenseTrend(Request $request): JsonResponse
    {
        [$associationId, $errorResponse] = $this->requireAssociation();
        if ($errorResponse) return $errorResponse;

        $period = $request->input('period', '12_months');
        $data = $this->reportingService->getExpenseTrend($associationId, $period);

        return $this->success($data, 'Expense trend retrieved');
    }

    /**
     * Revenue breakdown by financial item category.
     */
    public function revenueByCategory(Request $request): JsonResponse
    {
        [$associationId, $errorResponse] = $this->requireAssociation();
        if ($errorResponse) return $errorResponse;

        $data = $this->reportingService->getRevenueByCategory(
            $associationId,
            $request->input('date_from'),
            $request->input('date_to')
        );

        return $this->success($data, 'Revenue by category retrieved');
    }

    /**
     * Expense breakdown by category (public-visible only).
     */
    public function expenseByCategory(Request $request): JsonResponse
    {
        [$associationId, $errorResponse] = $this->requireAssociation();
        if ($errorResponse) return $errorResponse;

        $data = $this->reportingService->getExpenseByCategory(
            $associationId,
            $request->input('date_from'),
            $request->input('date_to')
        );

        return $this->success($data, 'Expense by category retrieved');
    }

    /**
     * Payment method distribution.
     */
    public function paymentMethods(Request $request): JsonResponse
    {
        [$associationId, $errorResponse] = $this->requireAssociation();
        if ($errorResponse) return $errorResponse;

        $data = $this->reportingService->getPaymentMethodBreakdown(
            $associationId,
            $request->input('date_from'),
            $request->input('date_to')
        );

        return $this->success($data, 'Payment methods retrieved');
    }

    /**
     * Monthly income vs expense (net cashflow).
     */
    public function netCashflow(Request $request): JsonResponse
    {
        [$associationId, $errorResponse] = $this->requireAssociation();
        if ($errorResponse) return $errorResponse;

        $period = $request->input('period', '12_months');
        $data = $this->reportingService->getNetCashflow($associationId, $period);

        return $this->success($data, 'Net cashflow retrieved');
    }

    /**
     * Member overview stats.
     */
    public function memberOverview(): JsonResponse
    {
        [$associationId, $errorResponse] = $this->requireAssociation();
        if ($errorResponse) return $errorResponse;

        $data = $this->reportingService->getMemberOverview($associationId);

        return $this->success($data, 'Member overview retrieved');
    }

    /**
     * Event overview stats.
     */
    public function eventOverview(Request $request): JsonResponse
    {
        [$associationId, $errorResponse] = $this->requireAssociation();
        if ($errorResponse) return $errorResponse;

        $period = $request->input('period', '12_months');
        $data = $this->reportingService->getEventOverview($associationId, $period);

        return $this->success($data, 'Event overview retrieved');
    }

    /**
     * Monthly event attendance trend data.
     */
    public function eventAttendanceTrend(Request $request): JsonResponse
    {
        [$associationId, $errorResponse] = $this->requireAssociation();
        if ($errorResponse) return $errorResponse;

        $period = $request->input('period', '12_months');
        $data = $this->reportingService->getEventAttendanceTrend($associationId, $period);

        return $this->success($data, 'Event attendance trend retrieved');
    }

    /**
     * Per-event revenue breakdown.
     */
    public function eventRevenueBreakdown(Request $request): JsonResponse
    {
        [$associationId, $errorResponse] = $this->requireAssociation();
        if ($errorResponse) return $errorResponse;

        $period = $request->input('period', '12_months');
        $data = $this->reportingService->getEventRevenueBreakdown($associationId, $period);

        return $this->success($data, 'Event revenue breakdown retrieved');
    }

    /**
     * Project overview stats (graceful degradation if module disabled).
     */
    public function projectOverview(): JsonResponse
    {
        [$associationId, $errorResponse] = $this->requireAssociation();
        if ($errorResponse) return $errorResponse;

        $data = $this->reportingService->getProjectOverview($associationId);

        return $this->success($data, 'Project overview retrieved');
    }

    // =========================================================================
    // Admin-Only Endpoints
    // =========================================================================

    /**
     * Per-member dues collection status.
     */
    public function duesCollection(Request $request): JsonResponse
    {
        [$associationId, $errorResponse] = $this->requireAssociation();
        if ($errorResponse) return $errorResponse;

        $financialItemId = $request->input('financial_item_id') ? (int) $request->input('financial_item_id') : null;
        $data = $this->reportingService->getDuesCollectionReport($associationId, $financialItemId);

        return $this->success($data, 'Dues collection report retrieved');
    }

    /**
     * All members with overdue obligations.
     */
    public function overdueMembers(): JsonResponse
    {
        [$associationId, $errorResponse] = $this->requireAssociation();
        if ($errorResponse) return $errorResponse;

        $data = $this->reportingService->getOverdueReport($associationId);

        return $this->success($data, 'Overdue members report retrieved');
    }

    /**
     * Compliance rate per active financial item.
     */
    public function memberCompliance(): JsonResponse
    {
        [$associationId, $errorResponse] = $this->requireAssociation();
        if ($errorResponse) return $errorResponse;

        $data = $this->reportingService->getMemberComplianceRate($associationId);

        return $this->success($data, 'Member compliance report retrieved');
    }

    /**
     * Member growth trend (admin detail).
     */
    public function memberGrowth(Request $request): JsonResponse
    {
        [$associationId, $errorResponse] = $this->requireAssociation();
        if ($errorResponse) return $errorResponse;

        $period = $request->input('period', '12_months');
        $data = $this->reportingService->getMemberGrowthTrend($associationId, $period);

        return $this->success($data, 'Member growth trend retrieved');
    }

    /**
     * Export a report to XLSX.
     */
    public function exportReport(Request $request, string $reportType)
    {
        [$associationId, $errorResponse] = $this->requireAssociation();
        if ($errorResponse) return $errorResponse;

        $timestamp = now()->format('Y-m-d_His');

        return match ($reportType) {
            'dues-collection' => Excel::download(
                new DuesCollectionExport(
                    $associationId,
                    $request->input('financial_item_id') ? (int) $request->input('financial_item_id') : null,
                    $this->reportingService
                ),
                "dues-collection-{$timestamp}.xlsx"
            ),
            'overdue-members' => Excel::download(
                new OverdueMembersExport($associationId, $this->reportingService),
                "overdue-members-{$timestamp}.xlsx"
            ),
            'payment-history' => Excel::download(
                new PaymentHistoryExport(
                    $associationId,
                    $request->input('date_from'),
                    $request->input('date_to')
                ),
                "payment-history-{$timestamp}.xlsx"
            ),
            'expense-summary' => Excel::download(
                new ExpenseSummaryExport(
                    $associationId,
                    $request->input('date_from'),
                    $request->input('date_to')
                ),
                "expense-summary-{$timestamp}.xlsx"
            ),
            'member-list' => Excel::download(
                new MemberListExport($associationId),
                "member-list-{$timestamp}.xlsx"
            ),
            'event-attendees' => Excel::download(
                new EventAttendeesExport(
                    $associationId,
                    $request->input('date_from'),
                    $request->input('date_to')
                ),
                "event-attendees-{$timestamp}.xlsx"
            ),
            default => $this->error('Invalid report type', null, 422),
        };
    }
}
