<?php

declare(strict_types=1);

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Http\Requests\StoreCouponRequest;
use App\Models\Coupon;
use App\Models\Plan;
use Illuminate\Http\RedirectResponse;
use Inertia\Inertia;
use Inertia\Response;

class CouponController extends Controller
{
    public function index(): Response
    {
        $coupons = Coupon::query()
            ->withCount('redemptions')
            ->withSum('redemptions', 'discount_amount')
            ->withMax('redemptions', 'created_at')
            ->orderByDesc('created_at')
            ->paginate(25);

        return Inertia::render('Admin/Coupons/Index', [
            'coupons' => $coupons,
        ]);
    }

    public function show(Coupon $coupon): Response
    {
        $coupon->loadCount('redemptions');

        $redemptions = $coupon->redemptions()
            ->with(['user:id,name,email', 'subscription:id,type,stripe_status'])
            ->orderByDesc('created_at')
            ->paginate(25);

        $stats = [
            'total_redemptions' => $coupon->redemptions_count,
            'total_discount' => (float) $coupon->redemptions()->sum('discount_amount'),
            'latest_redemption' => $coupon->redemptions()->max('created_at'),
        ];

        return Inertia::render('Admin/Coupons/Show', [
            'coupon' => $coupon,
            'redemptions' => $redemptions,
            'stats' => $stats,
        ]);
    }

    public function create(): Response
    {
        $plans = Plan::query()
            ->where('status', 'active')
            ->orderBy('name')
            ->get(['id', 'name', 'service_type']);

        return Inertia::render('Admin/Coupons/Create', [
            'plans' => $plans,
        ]);
    }

    public function store(StoreCouponRequest $request): RedirectResponse
    {
        Coupon::query()->create([
            'code' => strtoupper($request->validated('code')),
            'type' => $request->validated('type'),
            'value' => $request->validated('value'),
            'currency' => 'USD',
            'max_uses' => $request->validated('max_uses'),
            'applies_to' => $request->validated('applies_to'),
            'expires_at' => $request->validated('expires_at'),
            'active' => true,
        ]);

        return redirect()
            ->route('admin.coupons.index')
            ->with('success', 'Coupon created successfully.');
    }

    public function edit(Coupon $coupon): Response
    {
        $plans = Plan::query()
            ->where('status', 'active')
            ->orderBy('name')
            ->get(['id', 'name', 'service_type']);

        $redemptions = $coupon->redemptions()
            ->with('user:id,name,email')
            ->orderByDesc('created_at')
            ->get();

        return Inertia::render('Admin/Coupons/Edit', [
            'coupon' => $coupon,
            'plans' => $plans,
            'redemptions' => $redemptions,
        ]);
    }

    public function update(StoreCouponRequest $request, Coupon $coupon): RedirectResponse
    {
        $coupon->update([
            'code' => strtoupper($request->validated('code')),
            'type' => $request->validated('type'),
            'value' => $request->validated('value'),
            'max_uses' => $request->validated('max_uses'),
            'applies_to' => $request->validated('applies_to'),
            'expires_at' => $request->validated('expires_at'),
        ]);

        return redirect()
            ->route('admin.coupons.index')
            ->with('success', 'Coupon updated successfully.');
    }

    public function destroy(Coupon $coupon): RedirectResponse
    {
        $coupon->update(['active' => false]);

        return redirect()
            ->route('admin.coupons.index')
            ->with('success', 'Coupon deactivated successfully.');
    }

    public function redemptions(): Response|\Symfony\Component\HttpFoundation\StreamedResponse
    {
        $query = \App\Models\CouponRedemption::query()
            ->with(['coupon:id,code,type,value', 'user:id,name,email', 'subscription:id,type,stripe_status']);

        // Filter by coupon
        if (request()->filled('coupon_id')) {
            $query->where('coupon_id', request('coupon_id'));
        }

        // Filter by customer (search by name or email)
        if (request()->filled('customer')) {
            $search = request('customer');
            $query->whereHas('user', function ($q) use ($search): void {
                $q->where('name', 'LIKE', "%{$search}%")
                    ->orWhere('email', 'LIKE', "%{$search}%");
            });
        }

        // Filter by date range
        if (request()->filled('date_from')) {
            $query->whereDate('created_at', '>=', request('date_from'));
        }

        if (request()->filled('date_to')) {
            $query->whereDate('created_at', '<=', request('date_to'));
        }

        // Handle CSV export
        if (request()->filled('export') && request('export') === 'csv') {
            return $this->exportRedemptionsToCSV($query);
        }

        $redemptions = $query->orderByDesc('created_at')->paginate(25);

        // Get all coupons for filter dropdown
        $coupons = Coupon::query()
            ->orderBy('code')
            ->get(['id', 'code']);

        // Calculate stats
        $statsQuery = \App\Models\CouponRedemption::query();

        // Apply same filters to stats
        if (request()->filled('coupon_id')) {
            $statsQuery->where('coupon_id', request('coupon_id'));
        }

        if (request()->filled('customer')) {
            $search = request('customer');
            $statsQuery->whereHas('user', function ($q) use ($search): void {
                $q->where('name', 'LIKE', "%{$search}%")
                    ->orWhere('email', 'LIKE', "%{$search}%");
            });
        }

        if (request()->filled('date_from')) {
            $statsQuery->whereDate('created_at', '>=', request('date_from'));
        }

        if (request()->filled('date_to')) {
            $statsQuery->whereDate('created_at', '<=', request('date_to'));
        }

        $stats = [
            'total_redemptions' => $statsQuery->count(),
            'total_discount' => (float) $statsQuery->sum('discount_amount'),
            'unique_customers' => $statsQuery->distinct('user_id')->count('user_id'),
            'unique_coupons' => $statsQuery->distinct('coupon_id')->count('coupon_id'),
        ];

        return Inertia::render('Admin/Coupons/Redemptions', [
            'redemptions' => $redemptions,
            'coupons' => $coupons,
            'stats' => $stats,
            'filters' => request()->only(['coupon_id', 'customer', 'date_from', 'date_to']),
        ]);
    }

    private function exportRedemptionsToCSV(\Illuminate\Database\Eloquent\Builder $query): \Symfony\Component\HttpFoundation\StreamedResponse
    {
        $headers = [
            'Content-Type' => 'text/csv',
            'Content-Disposition' => 'attachment; filename="coupon-redemptions-'.now()->format('Y-m-d-His').'.csv"',
        ];

        $callback = function () use ($query): void {
            $file = fopen('php://output', 'w');

            // CSV headers
            fputcsv($file, [
                'Redemption ID',
                'Coupon Code',
                'Coupon Type',
                'Coupon Value',
                'Customer Name',
                'Customer Email',
                'Subscription ID',
                'Subscription Status',
                'Discount Amount',
                'Redeemed At',
            ]);

            // Stream results in chunks to handle large datasets
            $query->orderByDesc('created_at')->chunk(1000, function ($redemptions) use ($file): void {
                foreach ($redemptions as $redemption) {
                    fputcsv($file, [
                        $redemption->id,
                        $redemption->coupon?->code ?? 'N/A',
                        $redemption->coupon?->type ?? 'N/A',
                        $redemption->coupon?->value ?? 'N/A',
                        $redemption->user?->name ?? 'Deleted User',
                        $redemption->user?->email ?? 'N/A',
                        $redemption->subscription?->id ?? 'N/A',
                        $redemption->subscription?->stripe_status ?? 'N/A',
                        $redemption->discount_amount,
                        $redemption->created_at->format('Y-m-d H:i:s'),
                    ]);
                }
            });

            fclose($file);
        };

        return response()->stream($callback, 200, $headers);
    }
}
