<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Student;
use App\Models\Course;
use App\Models\StudentCourse;
use App\Models\PaymentRecord;
use App\Models\ActivityLog;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Inertia\Inertia;

class PartnerController extends Controller
{
    public function dashboard(Request $request)
    {
        $partner = Auth::guard('partner')->user();
        $centerId = $partner->center_id;
        
        $query = Student::with(['courses', 'center'])->where('center_id', $centerId);
        
        if ($request->search) {
            $query->where(function($q) use ($request) {
                $q->where('name', 'like', '%' . $request->search . '%')
                  ->orWhere('state_code', 'like', '%' . $request->search . '%')
                  ->orWhere('email', 'like', '%' . $request->search . '%');
            });
        }
        
        $students = $query->latest()->paginate(10)->withQueryString();
        
        // Time range filtering
        $timeFilter = $request->time_filter ?? 'current_month';
        $customMonth = $request->custom_month;
        $customYear = $request->custom_year ?? now()->year;
        
        [$startDate, $endDate, $timeLabel] = $this->getTimeRange($timeFilter, $customMonth, $customYear);
        
        // Create base queries to avoid conflicts
        $baseStudentQuery = Student::where('center_id', $centerId);
        $baseEnrollmentQuery = StudentCourse::whereHas('student', function($q) use ($centerId) {
            $q->where('center_id', $centerId);
        });
        
        $metrics = [
            'total_students' => (clone $baseStudentQuery)->count(),
            'period_students' => (clone $baseStudentQuery)->whereBetween('students.created_at', [$startDate, $endDate])->count(),
            'total_enrollments' => (clone $baseEnrollmentQuery)->count(),
            'period_enrollments' => (clone $baseEnrollmentQuery)->whereBetween('student_courses.created_at', [$startDate, $endDate])->count(),
            'outstanding_amount' => (clone $baseEnrollmentQuery)->join('courses', 'student_courses.course_id', '=', 'courses.id')
              ->selectRaw('SUM(CASE WHEN (courses.price - COALESCE(student_courses.amount_paid, 0)) > 0 THEN (courses.price - COALESCE(student_courses.amount_paid, 0)) ELSE 0 END) as outstanding')
              ->value('outstanding') ?: 0,
            'period_certificates' => (clone $baseEnrollmentQuery)->where('student_courses.is_certified', true)
              ->whereBetween('student_courses.certification_date', [$startDate, $endDate])
              ->count(),
            'total_certificates' => (clone $baseEnrollmentQuery)->where('student_courses.is_certified', true)->count(),
            'period_payments' => (clone $baseEnrollmentQuery)->where('student_courses.payment_status', 'paid')
              ->whereBetween('student_courses.updated_at', [$startDate, $endDate])
              ->count(),
            'total_payments' => (clone $baseEnrollmentQuery)->where('student_courses.payment_status', 'paid')->count(),
        ];
        
        return Inertia::render('Partner/Dashboard', [
            'students' => $students,
            'metrics' => $metrics,
            'partner' => $partner->load('center'),
            'timeLabel' => $timeLabel,
            'filters' => $request->only(['time_filter', 'custom_month', 'custom_year', 'search'])
        ]);
    }
    
    private function getTimeRange($timeFilter, $customMonth = null, $customYear = null)
    {
        $now = now();
        
        switch ($timeFilter) {
            case 'current_month':
                $start = $now->copy()->startOfMonth();
                $end = $now->copy()->endOfMonth();
                $label = 'This Month (' . $start->format('M Y') . ')';
                break;
                
            case 'last_month':
                $start = $now->copy()->subMonth()->startOfMonth();
                $end = $now->copy()->subMonth()->endOfMonth();
                $label = 'Last Month (' . $start->format('M Y') . ')';
                break;
                
            case 'current_year':
                $start = $now->copy()->startOfYear();
                $end = $now->copy()->endOfYear();
                $label = 'This Year (' . $start->format('Y') . ')';
                break;
                
            case 'last_year':
                $start = $now->copy()->subYear()->startOfYear();
                $end = $now->copy()->subYear()->endOfYear();
                $label = 'Last Year (' . $start->format('Y') . ')';
                break;
                
            case 'custom_month':
                if ($customMonth && $customYear) {
                    $start = now()->setYear($customYear)->setMonth($customMonth)->startOfMonth();
                    $end = now()->setYear($customYear)->setMonth($customMonth)->endOfMonth();
                    $label = $start->format('M Y');
                } else {
                    // Fallback to current month
                    $start = $now->copy()->startOfMonth();
                    $end = $now->copy()->endOfMonth();
                    $label = 'This Month (' . $start->format('M Y') . ')';
                }
                break;
                
            case 'all_time':
            default:
                $start = now()->subYears(10);
                $end = now()->addYear();
                $label = 'All Time';
                break;
        }
        
        return [$start, $end, $label];
    }
    
    public function createStudent()
    {
        $partner = Auth::guard('partner')->user();
        $courses = Course::where('is_active', true)->get();
        
        return Inertia::render('Partner/CreateStudent', [
            'courses' => $courses,
            'partner' => $partner->load('center')
        ]);
    }
    
    public function storeStudent(Request $request)
    {
        $partner = Auth::guard('partner')->user();
        
        $validated = $request->validate([
            'name' => 'required|string|max:255',
            'state_code' => 'required|string|unique:students,state_code|max:20',
            'email' => 'required|email|max:255',
            'phone' => 'required|string|max:20',
            'enrollment_date' => 'required|date',
            'courses' => 'required|array|min:1',
            'courses.*.course_id' => 'required|exists:courses,id',
            'courses.*.payment_status' => 'required|in:pending,paid,overdue',
        ]);

        $student = Student::create([
            'name' => $validated['name'],
            'state_code' => $validated['state_code'],
            'email' => $validated['email'],
            'phone' => $validated['phone'],
            'center' => $partner->center->name,
            'center_id' => $partner->center_id,
            'enrollment_date' => $validated['enrollment_date'],
            'created_by_type' => 'partner',
            'created_by_id' => $partner->id,
            'created_by_name' => $partner->name,
        ]);

        foreach ($validated['courses'] as $courseData) {
            StudentCourse::create([
                'student_id' => $student->id,
                'course_id' => $courseData['course_id'],
                'payment_status' => $courseData['payment_status'],
                'enrollment_date' => $validated['enrollment_date'],
            ]);
        }

        return redirect()->route('partner.dashboard')->with('success', 'Student enrolled successfully!');
    }
    
    public function enrollments(Request $request)
    {
        $partner = Auth::guard('partner')->user();
        $centerId = $partner->center_id;
        
        $query = StudentCourse::with(['student', 'course', 'paymentRecords'])
                             ->whereHas('student', function($q) use ($centerId) {
                                 $q->where('center_id', $centerId);
                             });
        
        // Course filter
        if ($request->course_id) {
            $query->where('course_id', $request->course_id);
        }
        
        // Student name search
        if ($request->search) {
            $query->whereHas('student', function($q) use ($request) {
                $q->where('name', 'like', '%' . $request->search . '%')
                  ->orWhere('state_code', 'like', '%' . $request->search . '%');
            });
        }
        
        // Date filter
        if ($request->date_from) {
            $query->whereDate('enrollment_date', '>=', $request->date_from);
        }
        if ($request->date_to) {
            $query->whereDate('enrollment_date', '<=', $request->date_to);
        }
        
        // Create metrics query with same filters
        $metricsQuery = StudentCourse::with(['course'])
                                    ->whereHas('student', function($q) use ($centerId) {
                                        $q->where('center_id', $centerId);
                                    });
        
        if ($request->course_id) {
            $metricsQuery->where('course_id', $request->course_id);
        }
        
        if ($request->search) {
            $metricsQuery->whereHas('student', function($q) use ($request) {
                $q->where('name', 'like', '%' . $request->search . '%')
                  ->orWhere('state_code', 'like', '%' . $request->search . '%');
            });
        }
        
        if ($request->date_from) {
            $metricsQuery->whereDate('enrollment_date', '>=', $request->date_from);
        }
        if ($request->date_to) {
            $metricsQuery->whereDate('enrollment_date', '<=', $request->date_to);
        }
        
        $metrics = [
            'total_enrollments' => (clone $metricsQuery)->count(),
            'total_income' => (clone $metricsQuery)->sum('amount_paid'),
            'outstanding_amount' => (clone $metricsQuery)->join('courses', 'student_courses.course_id', '=', 'courses.id')
                                                         ->selectRaw('SUM(CASE WHEN (courses.price - COALESCE(student_courses.amount_paid, 0)) > 0 THEN (courses.price - COALESCE(student_courses.amount_paid, 0)) ELSE 0 END) as outstanding')
                                                         ->value('outstanding') ?: 0,
            'issued_certificates' => (clone $metricsQuery)->where('is_certified', true)->count(),
            'due_certificates' => (clone $metricsQuery)->join('courses', 'student_courses.course_id', '=', 'courses.id')
                                                        ->whereRaw('CAST(COALESCE(student_courses.amount_paid, 0) AS DECIMAL(10,2)) >= CAST(courses.price AS DECIMAL(10,2))')
                                                        ->where('student_courses.is_certified', false)
                                                        ->count()
        ];
        
        $enrollments = $query->latest()->paginate(15)->withQueryString();
        $courses = Course::where('is_active', true)->get();
        
        return Inertia::render('Partner/Enrollments', [
            'enrollments' => $enrollments,
            'courses' => $courses,
            'partner' => $partner->load('center'),
            'metrics' => $metrics,
            'filters' => $request->only(['course_id', 'search', 'date_from', 'date_to'])
        ]);
    }
    
    public function addPayment(Request $request, StudentCourse $enrollment)
    {
        $partner = Auth::guard('partner')->user();
        $enrollment->load('course');
        
        // Ensure enrollment belongs to partner's center
        if ($enrollment->student->center_id !== $partner->center_id) {
            return back()->with('error', 'Unauthorized access.');
        }

        $validated = $request->validate([
            'amount' => 'required|numeric|min:0.01',
            'payment_method' => 'nullable|string|max:255',
            'notes' => 'nullable|string',
            'payment_date' => 'required|date',
        ]);

        // Validate that total payment doesn't exceed course price
        $newTotal = $enrollment->amount_paid + $validated['amount'];
        if ($newTotal > $enrollment->course->price) {
            $remaining = $enrollment->course->price - $enrollment->amount_paid;
            return back()->with('error', "Payment amount exceeds remaining balance. Maximum allowed: ₦{$remaining}");
        }

        PaymentRecord::create([
            'student_course_id' => $enrollment->id,
            'amount' => $validated['amount'],
            'payment_method' => $validated['payment_method'],
            'notes' => $validated['notes'],
            'payment_date' => $validated['payment_date'],
            'recorded_by_type' => 'partner',
            'recorded_by_id' => $partner->id,
            'recorded_by_name' => $partner->name,
        ]);

        $enrollment->amount_paid = $newTotal;
        $enrollment->save();

        ActivityLog::create([
            'student_id' => $enrollment->student_id,
            'action' => 'payment_added',
            'description' => "Payment of ₦{$validated['amount']} added by {$partner->name}",
            'performed_by_type' => 'partner',
            'performed_by_id' => $partner->id,
            'performed_by_name' => $partner->name,
            'new_values' => ['amount' => $validated['amount'], 'total_paid' => $enrollment->amount_paid],
        ]);

        return back()->with('success', 'Payment recorded successfully!');
    }
    
    public function updatePaymentStatus(Request $request, StudentCourse $enrollment)
    {
        $partner = Auth::guard('partner')->user();
        
        // Ensure enrollment belongs to partner's center
        if ($enrollment->student->center_id !== $partner->center_id) {
            return back()->with('error', 'Unauthorized access.');
        }

        $validated = $request->validate([
            'payment_status' => 'required|in:pending,paid,overdue',
        ]);

        $enrollment->update([
            'payment_status' => $validated['payment_status']
        ]);

        ActivityLog::create([
            'student_id' => $enrollment->student_id,
            'action' => 'payment_status_updated',
            'description' => "Payment status updated to {$validated['payment_status']} by {$partner->name}",
            'performed_by_type' => 'partner',
            'performed_by_id' => $partner->id,
            'performed_by_name' => $partner->name,
            'new_values' => ['payment_status' => $validated['payment_status']],
        ]);

        return back()->with('success', 'Payment status updated successfully!');
    }
    
    public function students(Request $request)
    {
        $partner = Auth::guard('partner')->user();
        $centerId = $partner->center_id;
        
        $query = Student::with(['courses', 'center'])->where('center_id', $centerId);
        
        if ($request->search) {
            $query->where(function($q) use ($request) {
                $q->where('name', 'like', '%' . $request->search . '%')
                  ->orWhere('state_code', 'like', '%' . $request->search . '%')
                  ->orWhere('email', 'like', '%' . $request->search . '%');
            });
        }
        
        $students = $query->latest()->paginate(15)->withQueryString();
        
        return Inertia::render('Partner/Students', [
            'students' => $students,
            'partner' => $partner->load('center'),
            'filters' => $request->only(['search'])
        ]);
    }
    
    public function courses(Request $request)
    {
        $partner = Auth::guard('partner')->user();
        
        $query = Course::where('is_active', true);
        
        if ($request->search) {
            $query->where(function($q) use ($request) {
                $q->where('name', 'like', '%' . $request->search . '%')
                  ->orWhere('description', 'like', '%' . $request->search . '%');
            });
        }
        
        $courses = $query->latest()->paginate(15)->withQueryString();
        
        return Inertia::render('Partner/Courses', [
            'courses' => $courses,
            'partner' => $partner->load('center'),
            'filters' => $request->only(['search'])
        ]);
    }
    
    public function viewRecords(StudentCourse $enrollment)
    {
        $partner = Auth::guard('partner')->user();
        
        // Ensure enrollment belongs to partner's center
        if ($enrollment->student->center_id !== $partner->center_id) {
            return back()->with('error', 'Unauthorized access.');
        }
        
        $enrollment->load(['student', 'course', 'paymentRecords']);
        
        $paymentRecords = $enrollment->paymentRecords()->latest()->get();
        $activityLogs = ActivityLog::where('student_id', $enrollment->student_id)->latest()->get();
        
        return Inertia::render('Partner/EnrollmentRecords', [
            'enrollment' => $enrollment,
            'paymentRecords' => $paymentRecords,
            'activityLogs' => $activityLogs,
            'partner' => $partner->load('center')
        ]);
    }
    
    public function certificates(Request $request)
    {
        $partner = Auth::guard('partner')->user();
        $centerId = $partner->center_id;
        
        $query = StudentCourse::with(['student.center', 'course'])
                             ->whereHas('student', function($q) use ($centerId) {
                                 $q->where('center_id', $centerId);
                             })
                             ->where('is_certified', true)
                             ->whereNotNull('certificate_number');
        
        if ($request->search) {
            $query->whereHas('student', function($q) use ($request) {
                $q->where('name', 'like', '%' . $request->search . '%')
                  ->orWhere('state_code', 'like', '%' . $request->search . '%');
            })->orWhere('certificate_number', 'like', '%' . $request->search . '%');
        }
        
        if ($request->course_id) {
            $query->where('course_id', $request->course_id);
        }
        
        $certificates = $query->latest('certification_date')->paginate(15)->withQueryString();
        $courses = Course::where('is_active', true)->get();
        
        return Inertia::render('Partner/Certificates', [
            'certificates' => $certificates,
            'courses' => $courses,
            'partner' => $partner->load('center'),
            'filters' => $request->only(['search', 'course_id'])
        ]);
    }
    
    public function manualCertificates(Request $request)
    {
        $partner = Auth::guard('partner')->user();
        $centerId = $partner->center_id;
        
        $query = \App\Models\ManualCertificateRecord::with('center')
                                                   ->where('center_id', $centerId);
        
        if ($request->search) {
            $query->where(function($q) use ($request) {
                $q->where('student_name', 'like', '%' . $request->search . '%')
                  ->orWhere('certificate_number', 'like', '%' . $request->search . '%')
                  ->orWhere('course_name', 'like', '%' . $request->search . '%');
            });
        }
        
        $records = $query->latest()->paginate(15)->withQueryString();
        $courses = Course::where('is_active', true)->get();
        
        // Calculate certificate counts if limit is enabled
        $certificateData = [];
        if (config('certificates.limit.enabled') && config('certificates.limit.show_counter')) {
            $totalCertificates = StudentCourse::where('is_certified', true)->count() + \App\Models\ManualCertificateRecord::count();
            $maxRecords = config('certificates.limit.max_records', 50);
            $certificateData = [
                'totalCertificates' => $totalCertificates,
                'maxRecords' => $maxRecords,
                'remainingSlots' => max(0, $maxRecords - $totalCertificates),
                'showCounter' => true,
                'showWarnings' => config('certificates.limit.show_warnings', true)
            ];
        } else {
            $certificateData = [
                'showCounter' => false,
                'showWarnings' => config('certificates.limit.show_warnings', true)
            ];
        }
        
        return Inertia::render('Partner/ManualCertificates', array_merge([
            'records' => $records,
            'courses' => $courses,
            'partner' => $partner->load('center'),
            'filters' => $request->only(['search'])
        ], $certificateData));
    }
    
    public function storeManualCertificate(Request $request)
    {
        $partner = Auth::guard('partner')->user();
        
        // Check certificate limit if enabled
        if (config('certificates.limit.enabled')) {
            $totalCertificates = StudentCourse::where('is_certified', true)->count() + \App\Models\ManualCertificateRecord::count();
            $maxRecords = config('certificates.limit.max_records', 50);
            if ($totalCertificates >= $maxRecords) {
                return back()->with('error', "Certificate limit reached ({$maxRecords} records maximum). Cannot add more certificates.");
            }
        }
        
        $validated = $request->validate([
            'certificate_number' => 'required|string|unique:manual_certificate_records,certificate_number|max:255',
            'student_name' => 'required|string|max:255',
            'course_id' => 'required|exists:courses,id',
            'issuance_date' => 'required|date',
            'notes' => 'nullable|string|max:500'
        ]);
        
        $course = Course::find($validated['course_id']);
        
        \App\Models\ManualCertificateRecord::create([
            'certificate_number' => $validated['certificate_number'],
            'student_name' => $validated['student_name'],
            'course_name' => $course->name,
            'issuance_date' => $validated['issuance_date'],
            'center_id' => $partner->center_id,
            'uploaded_by_type' => 'partner',
            'uploaded_by_id' => $partner->id,
            'uploaded_by_name' => $partner->name,
            'notes' => $validated['notes']
        ]);
        
        $successMessage = 'Manual certificate record added successfully!';
        if (config('certificates.limit.show_warnings')) {
            $successMessage .= ' This record is permanent and cannot be removed.';
        }
        
        return back()->with('success', $successMessage);
    }
}
