<?php

namespace App\Http\Controllers\Web;

use App\Http\Controllers\Controller;
use App\Models\AuditLog;
use App\Models\Expense;
use App\Models\PerformanceReview;
use App\Services\Forms\FormSubmissionExportService;
use App\Services\Reports\ReportCatalog;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Symfony\Component\HttpFoundation\StreamedResponse;

class ReportsController extends Controller
{
    public function __construct(
        protected ReportCatalog $catalog,
        protected FormSubmissionExportService $formExportService
    ) {}

    public function index()
    {
        $reports = $this->catalog->availableForUser(Auth::user());

        return view('reports.index', compact('reports'));
    }

    public function exportPerformance(Request $request): StreamedResponse
    {
        abort_unless(Auth::user()?->hasPermission('performance_view'), 403);

        $companyId = Auth::user()?->company_id;
        $cycleId = $request->integer('cycle_id') ?: null;

        $query = PerformanceReview::with(['user.department', 'reviewer', 'performanceCycle'])
            ->when($companyId, fn ($q) => $q->where('company_id', $companyId))
            ->when($cycleId, fn ($q) => $q->where('performance_cycle_id', $cycleId))
            ->orderByDesc('review_date');

        $reviews = $query->get();

        return response()->streamDownload(function () use ($reviews) {
            $handle = fopen('php://output', 'w');
            fputcsv($handle, ['Employee', 'Department', 'Cycle', 'Period', 'Reviewer', 'Rating', 'Status', 'Review Date']);
            foreach ($reviews as $review) {
                fputcsv($handle, [
                    $review->user?->name,
                    $review->user?->department?->name,
                    $review->performanceCycle?->name,
                    $review->period,
                    $review->reviewer?->name,
                    $review->rating,
                    $review->status,
                    $review->review_date?->format('Y-m-d'),
                ]);
            }
            fclose($handle);
        }, 'performance-reviews-' . now()->format('Ymd') . '.csv', ['Content-Type' => 'text/csv']);
    }

    public function exportAudit(Request $request): StreamedResponse
    {
        abort_unless(Auth::user()?->hasPermission('manage_settings'), 403);

        $companyId = Auth::user()?->company_id;
        $days = max(1, min(365, (int) $request->input('days', 30)));

        $logs = AuditLog::with('actor')
            ->when($companyId, fn ($q) => $q->where('company_id', $companyId))
            ->where('created_at', '>=', now()->subDays($days))
            ->orderByDesc('created_at')
            ->limit(5000)
            ->get();

        return response()->streamDownload(function () use ($logs) {
            $handle = fopen('php://output', 'w');
            fputcsv($handle, ['When', 'Actor', 'Action', 'Subject Type', 'Subject ID', 'IP', 'Details']);
            foreach ($logs as $log) {
                fputcsv($handle, [
                    $log->created_at?->toDateTimeString(),
                    $log->actor?->name,
                    $log->action,
                    $log->subject_type,
                    $log->subject_id,
                    $log->ip_address,
                    json_encode($log->properties),
                ]);
            }
            fclose($handle);
        }, 'audit-log-' . now()->format('Ymd') . '.csv', ['Content-Type' => 'text/csv']);
    }

    public function exportExpenses(Request $request, \App\Services\Finance\ExpenseScopeService $scopes): StreamedResponse
    {
        $user = Auth::user();
        abort_unless($user && app(\App\Services\Finance\FinanceNavService::class)->userHasAnyPermission($user, [
            'finance_view',
            'finance_treasury_view',
            'finance_operational',
            'finance_team_view',
            'finance_self_view',
            'expenses_create_own',
        ]), 403);

        $scope = $scopes->resolveScope($user, $request->input('scope'));
        $query = Expense::with(['claimant', 'account'])
            ->when($user->company_id, fn ($q) => $q->where('company_id', $user->company_id));

        $scopes->applyScope($query, $user, $scope);

        if ($request->filled('status')) {
            $query->where('status', $request->status);
        }

        $expenses = $query->orderByDesc('date')->get();

        return response()->streamDownload(function () use ($expenses) {
            $handle = fopen('php://output', 'w');
            fputcsv($handle, ['Employee', 'Category', 'Amount', 'Date', 'Status', 'Account', 'Description']);
            foreach ($expenses as $expense) {
                fputcsv($handle, [
                    $expense->claimant?->name,
                    $expense->category,
                    $expense->amount,
                    $expense->date?->format('Y-m-d'),
                    $expense->status,
                    $expense->account?->name,
                    $expense->description,
                ]);
            }
            fclose($handle);
        }, 'expenses-' . now()->format('Ymd') . '.csv', ['Content-Type' => 'text/csv']);
    }

    public function exportFormSubmissions(Request $request): StreamedResponse
    {
        abort_unless(Auth::user()?->hasPermission('documents_view'), 403);

        $user = Auth::user();
        $formId = $request->filled('form_id') ? $request->integer('form_id') : null;
        $days = $request->filled('days') ? $request->integer('days') : null;

        return $this->formExportService->streamCsv($user->company_id, $formId, $days);
    }
}
