<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use Carbon\Carbon;

class ReportController extends Controller
{
    /**
     * Generate a report
     * POST /api/reports/generate
     */
    public function generateReport(Request $request)
    {
        $request->validate([
            'type' => 'required|in:sales,operations,financial,performance,driver,vehicle,booking,payout',
            'date_from' => 'required|date',
            'date_to' => 'required|date|after_or_equal:date_from',
            'format' => 'nullable|in:json,csv,pdf',
            'filters' => 'nullable|array'
        ]);

        $user = auth()->user();
        $format = $request->format ?? 'json';

        try {
            $data = match ($request->type) {
                'sales' => $this->generateSalesReport($request),
                'operations' => $this->generateOperationsReport($request),
                'financial' => $this->generateFinancialReport($request),
                'performance' => $this->generatePerformanceReport($request),
                'driver' => $this->generateDriverReport($request),
                'vehicle' => $this->generateVehicleReport($request),
                'booking' => $this->generateBookingReport($request),
                'payout' => $this->generatePayoutReport($request),
            };

            // Store report in database
            $reportId = DB::table('reports')->insertGetId([
                'user_id' => $user->id,
                'type' => $request->type,
                'title' => ucfirst($request->type) . ' Report - ' . now()->format('M d, Y'),
                'date_from' => $request->date_from,
                'date_to' => $request->date_to,
                'format' => $format,
                'status' => 'completed',
                'data' => json_encode($data),
                'created_at' => now(),
                'updated_at' => now()
            ]);

            return response()->json([
                'success' => true,
                'message' => 'Report generated successfully',
                'data' => [
                    'report_id' => $reportId,
                    'type' => $request->type,
                    'format' => $format,
                    'generated_at' => now(),
                    'summary' => $data['summary'] ?? null
                ]
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to generate report: ' . $e->getMessage()
            ], 500);
        }
    }

    /**
     * Get report by ID
     * GET /api/reports/{report_id}
     */
    public function getReport($reportId)
    {
        $user = auth()->user();

        $report = DB::table('reports')
            ->where('id', $reportId)
            ->where('user_id', $user->id)
            ->first();

        if (!$report) {
            return response()->json([
                'success' => false,
                'message' => 'Report not found'
            ], 404);
        }

        return response()->json([
            'success' => true,
            'data' => [
                'id' => $report->id,
                'type' => $report->type,
                'title' => $report->title,
                'date_from' => $report->date_from,
                'date_to' => $report->date_to,
                'format' => $report->format,
                'status' => $report->status,
                'content' => json_decode($report->data),
                'created_at' => $report->created_at,
                'generated_by' => auth()->user()->name
            ]
        ]);
    }

    /**
     * Get user's reports list
     * GET /api/reports
     */
    public function listReports(Request $request)
    {
        $request->validate([
            'type' => 'nullable|in:sales,operations,financial,performance,driver,vehicle,booking,payout',
            'status' => 'nullable|in:pending,processing,completed,failed',
            'page' => 'nullable|integer|min:1',
            'limit' => 'nullable|integer|min:10|max:100'
        ]);

        $user = auth()->user();
        $page = $request->page ?? 1;
        $limit = $request->limit ?? 20;

        $query = DB::table('reports')->where('user_id', $user->id);

        if ($request->type) {
            $query->where('type', $request->type);
        }

        if ($request->status) {
            $query->where('status', $request->status);
        }

        $reports = $query->orderBy('created_at', 'desc')
            ->paginate($limit, ['*'], 'page', $page);

        return response()->json([
            'success' => true,
            'data' => $reports->items(),
            'pagination' => [
                'total' => $reports->total(),
                'per_page' => $reports->perPage(),
                'current_page' => $reports->currentPage(),
                'last_page' => $reports->lastPage()
            ]
        ]);
    }

    /**
     * Download report
     * GET /api/reports/{report_id}/download
     */
    public function downloadReport($reportId, Request $request)
    {
        $request->validate([
            'format' => 'required|in:csv,pdf,json'
        ]);

        $user = auth()->user();

        $report = DB::table('reports')
            ->where('id', $reportId)
            ->where('user_id', $user->id)
            ->first();

        if (!$report) {
            return response()->json([
                'success' => false,
                'message' => 'Report not found'
            ], 404);
        }

        // Generate download based on format
        return $this->formatReportDownload($report, $request->format);
    }

    /**
     * Create scheduled report
     * POST /api/reports/schedule
     */
    public function scheduleReport(Request $request)
    {
        $request->validate([
            'type' => 'required|in:sales,operations,financial,performance,driver,vehicle,booking,payout',
            'frequency' => 'required|in:daily,weekly,monthly,quarterly',
            'email_to' => 'required|email',
            'format' => 'nullable|in:json,csv,pdf',
            'filters' => 'nullable|array',
            'active' => 'nullable|boolean'
        ]);

        $user = auth()->user();

        try {
            $scheduledId = DB::table('scheduled_reports')->insertGetId([
                'user_id' => $user->id,
                'type' => $request->type,
                'frequency' => $request->frequency,
                'email_to' => $request->email_to,
                'format' => $request->format ?? 'pdf',
                'filters' => json_encode($request->filters ?? []),
                'active' => $request->active ?? true,
                'last_run_at' => null,
                'created_at' => now(),
                'updated_at' => now()
            ]);

            return response()->json([
                'success' => true,
                'message' => 'Scheduled report created successfully',
                'data' => [
                    'scheduled_id' => $scheduledId,
                    'type' => $request->type,
                    'frequency' => $request->frequency
                ]
            ], 201);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to schedule report: ' . $e->getMessage()
            ], 500);
        }
    }

    /**
     * Get scheduled reports
     * GET /api/reports/scheduled
     */
    public function getScheduledReports(Request $request)
    {
        $user = auth()->user();

        $scheduled = DB::table('scheduled_reports')
            ->where('user_id', $user->id)
            ->orderBy('created_at', 'desc')
            ->get();

        return response()->json([
            'success' => true,
            'data' => $scheduled
        ]);
    }

    /**
     * Delete scheduled report
     * DELETE /api/reports/scheduled/{scheduled_id}
     */
    public function deleteScheduledReport($scheduledId)
    {
        $user = auth()->user();

        $deleted = DB::table('scheduled_reports')
            ->where('id', $scheduledId)
            ->where('user_id', $user->id)
            ->delete();

        if (!$deleted) {
            return response()->json([
                'success' => false,
                'message' => 'Scheduled report not found'
            ], 404);
        }

        return response()->json([
            'success' => true,
            'message' => 'Scheduled report deleted successfully'
        ]);
    }

    /**
     * Generate sales report
     */
    private function generateSalesReport(Request $request)
    {
        $dateFrom = Carbon::parse($request->date_from);
        $dateTo = Carbon::parse($request->date_to);

        $bookingStats = DB::table('bookings')
            ->whereBetween('created_at', [$dateFrom, $dateTo])
            ->selectRaw('COUNT(*) as total_bookings, SUM(fare) as total_revenue, AVG(fare) as avg_fare')
            ->first();

        $paymentStats = DB::table('payments')
            ->whereBetween('created_at', [$dateFrom, $dateTo])
            ->selectRaw('COUNT(*) as total_payments, SUM(amount) as total_paid')
            ->first();

        return [
            'summary' => [
                'period' => $dateFrom->format('M d, Y') . ' - ' . $dateTo->format('M d, Y'),
                'total_bookings' => $bookingStats->total_bookings ?? 0,
                'total_revenue' => $bookingStats->total_revenue ?? 0,
                'avg_fare' => $bookingStats->avg_fare ?? 0,
                'total_payments' => $paymentStats->total_payments ?? 0,
                'total_paid' => $paymentStats->total_paid ?? 0
            ]
        ];
    }

    /**
     * Generate operations report
     */
    private function generateOperationsReport(Request $request)
    {
        $dateFrom = Carbon::parse($request->date_from);
        $dateTo = Carbon::parse($request->date_to);

        $completedBookings = DB::table('bookings')
            ->whereBetween('created_at', [$dateFrom, $dateTo])
            ->where('status', 'completed')
            ->count();

        $totalBookings = DB::table('bookings')
            ->whereBetween('created_at', [$dateFrom, $dateTo])
            ->count();

        $activeDrivers = DB::table('drivers')
            ->where('status', 'active')
            ->count();

        $avgRating = DB::table('trip_ratings')
            ->whereBetween('created_at', [$dateFrom, $dateTo])
            ->avg('rating') ?? 0;

        return [
            'summary' => [
                'period' => Carbon::parse($request->date_from)->format('M d, Y') . ' - ' . Carbon::parse($request->date_to)->format('M d, Y'),
                'completion_rate' => $totalBookings > 0 ? round(($completedBookings / $totalBookings) * 100, 2) : 0,
                'completed_bookings' => $completedBookings,
                'total_bookings' => $totalBookings,
                'active_drivers' => $activeDrivers,
                'avg_rating' => round($avgRating, 2)
            ]
        ];
    }

    /**
     * Generate financial report
     */
    private function generateFinancialReport(Request $request)
    {
        $dateFrom = Carbon::parse($request->date_from);
        $dateTo = Carbon::parse($request->date_to);

        $payouts = DB::table('payouts')
            ->whereBetween('created_at', [$dateFrom, $dateTo])
            ->selectRaw('COUNT(*) as total_payouts, SUM(amount) as total_amount')
            ->first();

        $commissions = DB::table('commissions')
            ->whereBetween('created_at', [$dateFrom, $dateTo])
            ->selectRaw('COUNT(*) as total_commissions, SUM(amount) as total_commission')
            ->first();

        return [
            'summary' => [
                'period' => $dateFrom->format('M d, Y') . ' - ' . $dateTo->format('M d, Y'),
                'total_payouts' => $payouts->total_payouts ?? 0,
                'payout_amount' => $payouts->total_amount ?? 0,
                'total_commissions' => $commissions->total_commissions ?? 0,
                'commission_amount' => $commissions->total_commission ?? 0,
                'net_revenue' => ($payouts->total_amount ?? 0) - ($commissions->total_commission ?? 0)
            ]
        ];
    }

    /**
     * Generate performance report
     */
    private function generatePerformanceReport(Request $request)
    {
        $dateFrom = Carbon::parse($request->date_from);
        $dateTo = Carbon::parse($request->date_to);

        $topDrivers = DB::table('drivers')
            ->join('bookings', 'drivers.id', '=', 'bookings.driver_id')
            ->whereBetween('bookings.created_at', [$dateFrom, $dateTo])
            ->selectRaw('drivers.id, drivers.name, COUNT(bookings.id) as trips, AVG(trip_ratings.rating) as avg_rating')
            ->leftJoin('trip_ratings', 'bookings.id', '=', 'trip_ratings.booking_id')
            ->groupBy('drivers.id', 'drivers.name')
            ->orderBy('trips', 'desc')
            ->limit(10)
            ->get();

        return [
            'summary' => [
                'period' => $dateFrom->format('M d, Y') . ' - ' . $dateTo->format('M d, Y'),
                'top_drivers' => $topDrivers->toArray()
            ]
        ];
    }

    /**
     * Generate driver report
     */
    private function generateDriverReport(Request $request)
    {
        $dateFrom = Carbon::parse($request->date_from);
        $dateTo = Carbon::parse($request->date_to);

        $driverStats = DB::table('drivers')
            ->join('bookings', 'drivers.id', '=', 'bookings.driver_id')
            ->whereBetween('bookings.created_at', [$dateFrom, $dateTo])
            ->selectRaw('COUNT(DISTINCT drivers.id) as total_drivers, COUNT(bookings.id) as total_trips')
            ->first();

        return [
            'summary' => [
                'period' => $dateFrom->format('M d, Y') . ' - ' . $dateTo->format('M d, Y'),
                'total_drivers' => $driverStats->total_drivers ?? 0,
                'total_trips' => $driverStats->total_trips ?? 0
            ]
        ];
    }

    /**
     * Generate vehicle report
     */
    private function generateVehicleReport(Request $request)
    {
        $dateFrom = Carbon::parse($request->date_from);
        $dateTo = Carbon::parse($request->date_to);

        $vehicleStats = DB::table('vehicles')
            ->join('bookings', 'vehicles.id', '=', 'bookings.vehicle_id')
            ->whereBetween('bookings.created_at', [$dateFrom, $dateTo])
            ->selectRaw('COUNT(DISTINCT vehicles.id) as total_vehicles, COUNT(bookings.id) as total_trips')
            ->first();

        return [
            'summary' => [
                'period' => $dateFrom->format('M d, Y') . ' - ' . $dateTo->format('M d, Y'),
                'total_vehicles' => $vehicleStats->total_vehicles ?? 0,
                'total_trips' => $vehicleStats->total_trips ?? 0
            ]
        ];
    }

    /**
     * Generate booking report
     */
    private function generateBookingReport(Request $request)
    {
        $dateFrom = Carbon::parse($request->date_from);
        $dateTo = Carbon::parse($request->date_to);

        $bookingStats = DB::table('bookings')
            ->whereBetween('created_at', [$dateFrom, $dateTo])
            ->selectRaw('
                COUNT(*) as total_bookings,
                SUM(CASE WHEN status = "completed" THEN 1 ELSE 0 END) as completed,
                SUM(CASE WHEN status = "cancelled" THEN 1 ELSE 0 END) as cancelled,
                SUM(CASE WHEN status = "pending" THEN 1 ELSE 0 END) as pending,
                SUM(fare) as total_fare
            ')
            ->first();

        return [
            'summary' => [
                'period' => $dateFrom->format('M d, Y') . ' - ' . $dateTo->format('M d, Y'),
                'total_bookings' => $bookingStats->total_bookings ?? 0,
                'completed' => $bookingStats->completed ?? 0,
                'cancelled' => $bookingStats->cancelled ?? 0,
                'pending' => $bookingStats->pending ?? 0,
                'total_fare' => $bookingStats->total_fare ?? 0
            ]
        ];
    }

    /**
     * Generate payout report
     */
    private function generatePayoutReport(Request $request)
    {
        $dateFrom = Carbon::parse($request->date_from);
        $dateTo = Carbon::parse($request->date_to);

        $payoutStats = DB::table('payouts')
            ->whereBetween('created_at', [$dateFrom, $dateTo])
            ->selectRaw('
                COUNT(*) as total_payouts,
                SUM(amount) as total_amount,
                SUM(CASE WHEN status = "completed" THEN 1 ELSE 0 END) as completed,
                SUM(CASE WHEN status = "pending" THEN 1 ELSE 0 END) as pending
            ')
            ->first();

        return [
            'summary' => [
                'period' => $dateFrom->format('M d, Y') . ' - ' . $dateTo->format('M d, Y'),
                'total_payouts' => $payoutStats->total_payouts ?? 0,
                'total_amount' => $payoutStats->total_amount ?? 0,
                'completed' => $payoutStats->completed ?? 0,
                'pending' => $payoutStats->pending ?? 0
            ]
        ];
    }

    /**
     * Format report for download
     */
    private function formatReportDownload($report, $format)
    {
        // Placeholder for format conversion logic
        // In production, use libraries like: 
        // - PDF: dompdf/dompdf
        // - CSV: league/csv

        return response()->json([
            'success' => true,
            'message' => 'Download prepared',
            'download_url' => "/reports/{$report->id}/download"
        ]);
    }
}
