<?php

namespace App\Http\Controllers;

use App\Models\Teacher;
use App\Models\User;
use App\Models\TeacherAttendance;
use App\Models\TeacherSalary;
use App\Models\TeacherLeave;
use App\Models\Classes;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Barryvdh\DomPDF\Facade\Pdf;

class TeacherController extends Controller
{
    /**
     * Display teacher listing
     */
    public function index()
    {
        $teachers = Teacher::with('user')
                          ->orderBy('joining_date', 'desc')
                          ->paginate(20);
        
        $stats = [
            'total' => Teacher::count(),
            'active' => Teacher::where('job_status', 'active')->count(),
            'permanent' => Teacher::where('employment_type', 'permanent')->count(),
            'contract' => Teacher::where('employment_type', 'contract')->count()
        ];

        return view('teachers.index', compact('teachers', 'stats'));
    }

    /**
     * Show create form
     */
    public function create()
    {
        $designations = Teacher::getDesignations();
        $departments = Teacher::getDepartments();
        $employmentTypes = Teacher::getEmploymentTypes();
        
        return view('teachers.create', compact('designations', 'departments', 'employmentTypes'));
    }

    /**
     * Store teacher
     */
    public function store(Request $request)
    {
        $validator = Validator::make($request->all(), [
            // Personal Info
            'name_bn' => 'required|string|max:255',
            'name_en' => 'required|string|max:255',
            'father_name' => 'required|string|max:255',
            'mother_name' => 'required|string|max:255',
            'date_of_birth' => 'required|date|before:today',
            'gender' => 'required|in:male,female,other',
            'blood_group' => 'nullable|in:A+,A-,B+,B-,O+,O-,AB+,AB-',
            'religion' => 'nullable|string|max:50',
            'nationality' => 'required|string|max:50',
            'nid_number' => 'required|string|unique:teachers',
            'phone' => 'required|string|max:20|unique:teachers',
            'email' => 'nullable|email|unique:teachers',
            'present_address' => 'required|string',
            
            // Professional Info
            'qualification' => 'required|string',
            'subject_specialization' => 'required|string',
            'designation' => 'required|string',
            'department' => 'required|string',
            'joining_date' => 'required|date',
            'employment_type' => 'required|string',
            
            // Salary Info
            'basic_salary' => 'required|numeric|min:0',
            'house_rent' => 'nullable|numeric|min:0',
            'medical_allowance' => 'nullable|numeric|min:0',
            'transport_allowance' => 'nullable|numeric|min:0',
            'other_allowance' => 'nullable|numeric|min:0',
            'bank_name' => 'nullable|string',
            'bank_account_no' => 'nullable|string',
            'bkash_number' => 'nullable|string',
            
            // Documents
            'photo' => 'nullable|image|mimes:jpeg,png,jpg|max:2048',
            'cv' => 'nullable|file|mimes:pdf,doc,docx|max:5120'
        ]);

        if ($validator->fails()) {
            return redirect()->back()
                           ->withErrors($validator)
                           ->withInput();
        }

        DB::beginTransaction();
        
        try {
            $data = $request->except('_token');
            $data['teacher_id'] = Teacher::generateTeacherId();
            
            // Calculate total salary
            $data['total_salary'] = $data['basic_salary'] + 
                                    ($data['house_rent'] ?? 0) + 
                                    ($data['medical_allowance'] ?? 0) + 
                                    ($data['transport_allowance'] ?? 0) + 
                                    ($data['other_allowance'] ?? 0);
            
            $data['job_status'] = 'active';
            $data['status'] = true;

            // Create user account
            $user = User::create([
                'name' => $data['name_en'],
                'name_bn' => $data['name_bn'],
                'email' => $data['email'] ?? $data['teacher_id'] . '@school.edu.bd',
                'phone' => $data['phone'],
                'password' => Hash::make($data['phone']),
                'role' => 'teacher'
            ]);
            
            $data['user_id'] = $user->id;

            // Upload photo
            if ($request->hasFile('photo')) {
                $file = $request->file('photo');
                $filename = 'teacher_' . time() . '_' . $data['teacher_id'] . '.' . $file->getClientOriginalExtension();
                $file->move(public_path('uploads/teachers/photos'), $filename);
                $data['photo'] = 'uploads/teachers/photos/' . $filename;
            }

            // Upload CV
            if ($request->hasFile('cv')) {
                $file = $request->file('cv');
                $filename = 'cv_' . time() . '_' . $data['teacher_id'] . '.' . $file->getClientOriginalExtension();
                $file->move(public_path('uploads/teachers/documents'), $filename);
                $data['cv'] = 'uploads/teachers/documents/' . $filename;
            }

            $teacher = Teacher::create($data);

            DB::commit();

            return redirect()->route('teachers.show', $teacher->id)
                           ->with('success', 'শিক্ষক সফলভাবে নিবন্ধন করা হয়েছে');

        } catch (\Exception $e) {
            DB::rollBack();
            \Log::error('Teacher creation failed: ' . $e->getMessage());
            
            return redirect()->back()
                           ->with('error', 'শিক্ষক নিবন্ধনে সমস্যা হয়েছে')
                           ->withInput();
        }
    }

    /**
     * Show teacher details
     */
    public function show($id)
    {
        $teacher = Teacher::with('user', 'classes')
                         ->findOrFail($id);
        
        $attendances = TeacherAttendance::where('teacher_id', $id)
                                       ->whereMonth('date', now()->month)
                                       ->whereYear('date', now()->year)
                                       ->get();

        $attendanceStats = [
            'present' => $attendances->where('status', 'present')->count(),
            'absent' => $attendances->where('status', 'absent')->count(),
            'late' => $attendances->where('status', 'late')->count(),
            'leave' => $attendances->where('status', 'leave')->count()
        ];

        $lastSalary = TeacherSalary::where('teacher_id', $id)
                                  ->latest()
                                  ->first();

        return view('teachers.show', compact('teacher', 'attendanceStats', 'lastSalary'));
    }

    /**
     * Show attendance page
     */
    public function attendance()
    {
        $teachers = Teacher::active()->orderBy('name_bn')->get();
        $today = now()->format('Y-m-d');
        
        $existingAttendance = TeacherAttendance::whereDate('date', today())
                                              ->get()
                                              ->keyBy('teacher_id');

        return view('teachers.attendance', compact('teachers', 'today', 'existingAttendance'));
    }

    /**
     * Store attendance
     */
    public function storeAttendance(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'date' => 'required|date',
            'attendance' => 'required|array',
            'attendance.*.status' => 'required|in:present,absent,late,half-day,leave'
        ]);

        if ($validator->fails()) {
            return redirect()->back()
                           ->withErrors($validator)
                           ->withInput();
        }

        DB::beginTransaction();
        
        try {
            foreach ($request->attendance as $teacherId => $data) {
                $attendance = TeacherAttendance::updateOrCreate(
                    [
                        'teacher_id' => $teacherId,
                        'date' => $request->date
                    ],
                    [
                        'check_in_time' => $data['check_in'] ?? null,
                        'check_out_time' => $data['check_out'] ?? null,
                        'status' => $data['status'],
                        'remarks' => $data['remarks'] ?? null
                    ]
                );

                $attendance->working_hours = $attendance->calculateWorkingHours();
                $attendance->save();
            }

            DB::commit();

            return redirect()->route('teachers.attendance')
                           ->with('success', 'উপস্থিতি সফলভাবে সংরক্ষণ করা হয়েছে');

        } catch (\Exception $e) {
            DB::rollBack();
            return redirect()->back()
                           ->with('error', 'উপস্থিতি সংরক্ষণে সমস্যা হয়েছে');
        }
    }

    /**
     * Show salary page
     */
    public function salary()
    {
        $teachers = Teacher::active()->get();
        $currentMonth = now()->month;
        $currentYear = now()->year;

        $salaries = TeacherSalary::with('teacher')
                                 ->where('salary_month', $currentMonth)
                                 ->where('salary_year', $currentYear)
                                 ->get()
                                 ->keyBy('teacher_id');

        return view('teachers.salary', compact('teachers', 'salaries', 'currentMonth', 'currentYear'));
    }

    /**
     * Generate monthly salary
     */
    public function generateSalary(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'month' => 'required|integer|between:1,12',
            'year' => 'required|integer|min:2020|max:2030'
        ]);

        if ($validator->fails()) {
            return redirect()->back()
                           ->withErrors($validator);
        }

        try {
            TeacherSalary::generateMonthlySalary($request->month, $request->year);

            return redirect()->route('teachers.salary')
                           ->with('success', 'মাসিক বেতন জেনারেট করা হয়েছে');

        } catch (\Exception $e) {
            return redirect()->back()
                           ->with('error', 'বেতন জেনারেট করতে সমস্যা হয়েছে');
        }
    }

    /**
     * Pay salary
     */
    public function paySalary(Request $request, $id)
    {
        $salary = TeacherSalary::findOrFail($id);

        $validator = Validator::make($request->all(), [
            'amount' => 'required|numeric|min:1|max:' . $salary->due_amount,
            'payment_method' => 'required|in:cash,bKash,bank,check',
            'payment_date' => 'required|date'
        ]);

        if ($validator->fails()) {
            return redirect()->back()
                           ->withErrors($validator)
                           ->withInput();
        }

        try {
            $salary->paid_amount += $request->amount;
            $salary->due_amount = $salary->net_payable - $salary->paid_amount;
            $salary->payment_date = $request->payment_date;
            $salary->payment_method = $request->payment_method;
            $salary->transaction_id = $request->transaction_id;
            
            if ($salary->due_amount <= 0) {
                $salary->payment_status = 'paid';
            } else {
                $salary->payment_status = 'partial';
            }
            
            $salary->save();

            return redirect()->route('teachers.salary')
                           ->with('success', 'বেতন পরিশোধ সফল হয়েছে');

        } catch (\Exception $e) {
            return redirect()->back()
                           ->with('error', 'বেতন পরিশোধে সমস্যা হয়েছে');
        }
    }

    /**
     * Show leave applications
     */
    public function leaves()
    {
        $leaves = TeacherLeave::with('teacher', 'approver')
                              ->orderBy('applied_date', 'desc')
                              ->paginate(20);

        return view('teachers.leaves', compact('leaves'));
    }

    /**
     * Apply for leave
     */
    public function applyLeave(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'teacher_id' => 'required|exists:teachers,id',
            'leave_type' => 'required|string',
            'start_date' => 'required|date|after_or_equal:today',
            'end_date' => 'required|date|after_or_equal:start_date',
            'reason' => 'required|string|max:500'
        ]);

        if ($validator->fails()) {
            return redirect()->back()
                           ->withErrors($validator)
                           ->withInput();
        }

        try {
            $data = $request->all();
            $data['applied_date'] = now();
            $data['total_days'] = now()->parse($request->start_date)
                                       ->diffInDays(now()->parse($request->end_date)) + 1;
            $data['status'] = 'pending';

            TeacherLeave::create($data);

            return redirect()->route('teachers.leaves')
                           ->with('success', 'ছুটির আবেদন জমা দেওয়া হয়েছে');

        } catch (\Exception $e) {
            return redirect()->back()
                           ->with('error', 'ছুটির আবেদনে সমস্যা হয়েছে');
        }
    }

    /**
     * Approve/reject leave
     */
    public function processLeave(Request $request, $id)
    {
        $leave = TeacherLeave::findOrFail($id);

        $validator = Validator::make($request->all(), [
            'status' => 'required|in:approved,rejected',
            'remarks' => 'nullable|string|max:255'
        ]);

        if ($validator->fails()) {
            return redirect()->back()
                           ->withErrors($validator);
        }

        try {
            $leave->status = $request->status;
            $leave->approved_by = auth()->id();
            $leave->approval_date = now();
            $leave->remarks = $request->remarks;
            $leave->save();

            return redirect()->route('teachers.leaves')
                           ->with('success', 'ছুটির আবেদন ' . ($request->status == 'approved' ? 'অনুমোদিত' : 'বাতিল') . ' হয়েছে');

        } catch (\Exception $e) {
            return redirect()->back()
                           ->with('error', 'প্রক্রিয়াকরণে সমস্যা হয়েছে');
        }
    }

    /**
     * Download salary slip
     */
    public function downloadSalarySlip($id)
    {
        $salary = TeacherSalary::with('teacher')->findOrFail($id);

        $pdf = Pdf::loadView('teachers.salary-slip-pdf', compact('salary'));
        
        return $pdf->download('salary_slip_' . $salary->teacher->teacher_id . '_' . $salary->salary_month . '_' . $salary->salary_year . '.pdf');
    }

    /**
     * Get teacher report
     */
    public function report(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'report_type' => 'required|in:list,attendance,salary,leave'
        ]);

        if ($validator->fails()) {
            return redirect()->back()
                           ->withErrors($validator);
        }

        switch ($request->report_type) {
            case 'list':
                $data = Teacher::with('classes')->get();
                return view('teachers.report-list', compact('data'));

            case 'attendance':
                $data = TeacherAttendance::with('teacher')
                                        ->whereMonth('date', $request->month ?? now()->month)
                                        ->whereYear('date', $request->year ?? now()->year)
                                        ->get();
                return view('teachers.report-attendance', compact('data'));

            case 'salary':
                $data = TeacherSalary::with('teacher')
                                    ->where('salary_month', $request->month ?? now()->month)
                                    ->where('salary_year', $request->year ?? now()->year)
                                    ->get();
                return view('teachers.report-salary', compact('data'));

            case 'leave':
                $data = TeacherLeave::with('teacher')
                                   ->whereYear('applied_date', $request->year ?? now()->year)
                                   ->get();
                return view('teachers.report-leave', compact('data'));
        }
    }
}