<?php

namespace App\Http\Controllers\Admin;

use App\Helpers\ApiResponse;
use App\Helpers\AuditLogHelper;
use App\Helpers\CacheHelper;
use App\Http\Controllers\Controller;
use App\Models\Teacher;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Str;
use Symfony\Component\HttpFoundation\Response;


class TeacherController extends Controller
{
    /**
     * Get all teachers
     */
    public function getAllTeachers(Request $request)
    {
        $auth = Auth::user();

        $perPage = $request->get('per_page', 15);
        $sortBy = $request->filled('sort_by') ? $request->get('sort_by') : 'order_no';
        $sortOrder = $request->get('sort_order');
        $sortOrder = $sortOrder == "1" ? 'asc' : ($sortOrder == "-1" ? 'desc' : 'asc');
        $search = $request->get('search', '');
        $cacheKey = 'teachers' . md5(json_encode([
            'search' => $search,
            'sort_by' => $sortBy,
            'sort_order' => $sortOrder,
            'per_page' => $perPage,
            'page' => $request->get('page', 1),
        ]));
        try {
            $teachers = CacheHelper::rememberByTag('teachers', $cacheKey, function () use ($auth, $request, $sortBy, $sortOrder, $search, $perPage) {

                // Super Admin
                if ($auth->role === 'super_admin') {
                    $query = Teacher::where('is_global', true);

                    // Optional: include franchisee teachers
                    if ($request->filled('franchisee_id')) {
                        $query->orWhere('franchisee_id', $request->franchisee_id);
                    }

                    // Search filter
                    if (!empty($search)) {
                        $query->where(function ($q) use ($search) {
                            $q->where('name', 'ILIKE', "%{$search}%")
                                ->orWhere('qualification', 'ILIKE', "%{$search}%");
                        });
                    }

                    //Dynamic sort
                    // Apply sorting (safe column list)
                    $allowed = ['name', 'qualification', 'order_no', 'created_at'];
                    $sortBy = in_array($sortBy, $allowed) ? $sortBy : 'order_no';

                    $teachers = $query->orderBy($sortBy, $sortOrder)
                        ->paginate($perPage);

                    return $teachers;
                    //return ApiResponse::success($teachers, "Teachers fetched successfully (super admin)");
                }

                // Franchise Users
                $franchiseId = $auth->franchisee_id;

                // Franchise-specific teachers
                $franchiseTeachers = Teacher::where('franchisee_id', $franchiseId);

                if (!empty($search)) {
                    $franchiseTeachers->where(function ($q) use ($search) {
                        $q->where('name', 'ILIKE', "%{$search}%")
                            ->orWhere('qualification', 'ILIKE', "%{$search}%");
                    });
                }

                $franchiseTeachers = $franchiseTeachers->get();

                // IDs of customized global teachers
                $customizedParentIds = $franchiseTeachers->pluck('parent_teachers_id')->filter()->toArray();

                // Global teachers not customized
                $globalTeachers = Teacher::where('is_global', true)
                    ->whereNotIn('id', $customizedParentIds);

                if (!empty($search)) {
                    $globalTeachers->where(function ($q) use ($search) {
                        $q->where('name', 'ILIKE', "%{$search}%")
                            ->orWhere('qualification', 'ILIKE', "%{$search}%");
                    });
                }

                $globalTeachers = $globalTeachers->get();

                // Merge franchise + global teachers
                $allTeachers = $franchiseTeachers->merge($globalTeachers)
                    ->sortBy([
                        [$sortBy, $sortOrder],
                    ])
                    ->values();

                // Manual pagination
                $page = $request->get('page', 1);
                $paginated = new \Illuminate\Pagination\LengthAwarePaginator(
                    $allTeachers->forPage($page, $perPage),
                    $allTeachers->count(),
                    $perPage,
                    $page,
                    ['path' => $request->url(), 'query' => $request->query()]
                );
                return $paginated;
            });
            return ApiResponse::success($teachers, "Teachers fetched successfully");
        } catch (\Throwable $e) {
            return ApiResponse::exception($e);
        }
    }

    //Create new Teachers
    public function saveTeachers(Request $request)
    {
        $messages = [
            'name.regex' => 'Parent name may only contain letters, numbers, and spaces.',
        ];

        $validator = Validator::make($request->all(), [
            'name' => ['required', 'string', 'max:150', 'regex:/^[a-zA-Z0-9\s]+$/'],
            'qualification' => 'nullable|string|max:255',
            'experience' => 'nullable|integer',
            'profile_image' => 'nullable',
            'status' => 'nullable|in:Active,Inactive',
        ], $messages);

        if ($validator->fails()) {
            return ApiResponse::error(
                $validator->errors()->first(),
                Response::HTTP_UNPROCESSABLE_ENTITY
            );
        }
        try {
            $auth = Auth::user();
            $data = $request->only([
                'name',
                'qualification',
                'experience',
                'profile_image',
                'status',
            ]);

            // Default status if not provided
            $data['status'] = $data['status'] ?? 'Inactive';

            // Role-based assignment
            if ($auth->role !== 'super_admin') {
                // Franchisee user → assign franchisee_id & cannot create global
                $data['franchisee_id'] = $auth->franchisee_id;
                $data['is_global'] = false;
                $data['parent_teachers_id'] = null;
            } else {
                // Super admin → global teacher
                $data['franchisee_id'] = null;
                $data['is_global'] = true;
                $data['parent_teachers_id'] = null;
            }

            // Handle profile image upload if exists
            // if ($request->hasFile('profile_image')) {
            //     $image = $request->file('profile_image');
            //     if ($image instanceof \Illuminate\Http\UploadedFile) {
            //         $path = $image->store('uploads/teachers', 'public');
            //         $data['profile_image'] = asset('storage/' . $path);
            //     }
            // }
            $teacher = Teacher::create($data);
            CacheHelper::forgetByTag('teachers');
            // ✅ ADD AUDIT LOG
            AuditLogHelper::created($teacher);
            return ApiResponse::success($teacher, "Teacher saved successfully");

        } catch (\Throwable $e) {
            return ApiResponse::exception($e);
        }
    }

    /**
     * Show a single teacher.
     */
    public function getTeachersById(string $id)
    {
        try {
            $teacher = Teacher::findOrFail($id);
            $auth = Auth::user();
            CacheHelper::forgetByTag('teachers');
            return ApiResponse::success($teacher, "Forms fetched successfully");
        } catch (\Throwable $e) {
            return ApiResponse::exception($e);
        }
    }

    /**
     * Update a teacher
     */
    public function updateTeachers(Request $request, string $id)
    {
        $auth = Auth::user();
        $teacher = Teacher::findOrFail($id);

        // Build validation rules based on what's being updated
        $rules = [];

        if ($request->has('name')) {
            $rules['name'] = 'required|string|max:150|regex:/^[a-zA-Z0-9\s]+$/';
        }
        if ($request->has('qualification')) {
            $rules['qualification'] = 'required|string|max:255';
        }
        if ($request->has('experience')) {
            $rules['experience'] = 'required|integer|min:0|max:50';
        }
        if ($request->has('profile_image')) {
            $rules['profile_image'] = 'nullable';
        }
        if ($request->has('status')) {
            $rules['status'] = 'nullable|in:Active,Inactive';
        }

        $validator = Validator::make($request->all(), $rules);

        if ($validator->fails()) {
            return ApiResponse::error(
                $validator->errors()->first(),
                Response::HTTP_UNPROCESSABLE_ENTITY
            );
        }

        try {
            // Only include fields that were actually sent in the request
            $data = [];
            $possibleFields = ['name', 'qualification', 'experience', 'status', 'profile_image'];
            foreach ($possibleFields as $field) {
                if ($request->has($field)) {
                    $data[$field] = $request->input($field);
                }
            }

            $response = null; // store response data

            // 🔹 Franchise users
            if ($auth->role !== 'super_admin') {

                if ($teacher->is_global) {
                    $existingCopy = Teacher::where('franchisee_id', $auth->franchisee_id)
                        ->where('parent_teachers_id', $teacher->id)
                        ->first();

                    if ($existingCopy) {
                        // ✅ TRACK CHANGES
                        $changes = [];
                        foreach ($data as $key => $val) {
                            if ($existingCopy->$key != $val) {
                                $changes[$key] = ['old' => $existingCopy->$key, 'new' => $val];
                            }
                        }
                        $existingCopy->update($data);
                        // ✅ ADD AUDIT LOG
                        AuditLogHelper::updated($existingCopy, $changes);
                        $response = ApiResponse::success($existingCopy, 'Franchise teacher updated successfully.');
                    } else {
                        $newTeacher = Teacher::create([
                            'franchisee_id' => $auth->franchisee_id,
                            'parent_teachers_id' => $teacher->id,
                            'name' => $data['name'] ?? $teacher->name,
                            'qualification' => $data['qualification'] ?? $teacher->qualification,
                            'experience' => $data['experience'] ?? $teacher->experience,
                            'profile_image' => $data['profile_image'] ?? $teacher->profile_image,
                            'status' => $data['status'] ?? $teacher->status,
                            'is_global' => false,
                        ]);
                        // ✅ ADD AUDIT LOG
                        AuditLogHelper::created($newTeacher, [
                            'description' => "Franchise-specific teacher created from global teacher ID: {$teacher->id}"
                        ]);
                        $response = ApiResponse::success($newTeacher, 'Franchise-specific teacher created.');
                    }
                } else {
                    if ($teacher->franchisee_id !== $auth->franchisee_id) {
                        return ApiResponse::error('Unauthorized to update this teacher', Response::HTTP_FORBIDDEN);
                    }

                    // ✅ TRACK CHANGES
                    $changes = [];
                    foreach ($data as $key => $val) {
                        if ($teacher->$key != $val) {
                            $changes[$key] = ['old' => $teacher->$key, 'new' => $val];
                        }
                    }

                    $teacher->update($data);
                    // ✅ ADD AUDIT LOG
                    AuditLogHelper::updated($teacher, $changes);
                    $response = ApiResponse::success($teacher, 'Franchise teacher updated successfully.');
                }
            } else {
                // 🔹 Super Admin
                // ✅ TRACK CHANGES
                $changes = [];
                foreach ($data as $key => $val) {
                    if ($teacher->$key != $val) {
                        $changes[$key] = ['old' => $teacher->$key, 'new' => $val];
                    }
                }

                $teacher->update($data);
                // ✅ ADD AUDIT LOG
                AuditLogHelper::updated($teacher, $changes);
                $response = ApiResponse::success($teacher, 'Teacher updated successfully (super admin)');
            }

            CacheHelper::forgetByTag('teachers');

            return $response;

        } catch (\Throwable $e) {
            return ApiResponse::exception($e);
        }
    }

    /**
     * Delete a teacher.
     */
    public function deleteTeachers(string $id)
    {
        $user = Auth::user();
        $teacher = Teacher::findOrFail($id);
        try {
            // Franchise users
            if ($user->role !== 'super_admin') {
                // Franchisee cannot delete global teachers
                if ($teacher->is_global) {
                    return ApiResponse::error(
                        "Unauthorized: Franchisee cannot delete global teachers",
                        Response::HTTP_FORBIDDEN
                    );
                }

                // Franchisee can only delete their own teachers
                if ($teacher->franchisee_id !== $user->franchisee_id) {
                    return ApiResponse::error(
                        "Unauthorized: You cannot delete another franchisee's teacher",
                        Response::HTTP_FORBIDDEN
                    );
                }

                // ✅ ADD AUDIT LOG
                AuditLogHelper::deleted($teacher);
                $teacher->delete();
                CacheHelper::forgetByTag('teachers');
                return ApiResponse::success($teacher, "Franchisee teacher deleted successfully");
            }

            // Super admin can delete anything
            // ✅ ADD AUDIT LOG
            AuditLogHelper::deleted($teacher);
            $teacher->delete();
            CacheHelper::forgetByTag('teachers');
            return ApiResponse::success($teacher, "Teacher deleted successfully");
        } catch (\Throwable $e) {
            return ApiResponse::exception($e);
        }
    }

    public function reorder(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'teachers' => 'required|array',
            'teachers.*.id' => 'required|uuid',
            'teachers.*.order_no' => 'required|integer',
        ]);

        if ($validator->fails()) {
            return ApiResponse::error(
                $validator->errors()->first(),
                Response::HTTP_UNPROCESSABLE_ENTITY
            );
        }
        try {
            $user = Auth::user();
            $req = $request->all();
            DB::transaction(function () use ($req, $user) {
                foreach ($req['teachers'] as $teachers) {
                    $id = $teachers['id'];
                    $orderNo = $teachers['order_no'];

                    if ($user->role === 'super_admin') {
                        Teacher::where('id', $id)->update(['order_no' => $orderNo]);
                        // ✅ ADD AUDIT LOG
                        AuditLogHelper::updated(
                            Teacher::find($id),
                            ['order_no' => $orderNo],
                            ['description' => "Teacher reordered to position {$orderNo}"]
                        );
                        continue;
                    }

                    $franchiseeId = $user->franchisee_id;
                    $override = Teacher::firstOrNew([
                        'franchisee_id' => $franchiseeId,
                        'id' => $id,
                    ]);

                    if (!$override->exists) {
                        $teacher = Teacher::findOrFail($id);
                        $override->fill([
                            'parent_teachers_id' => $teacher->id,
                            'name' => $teacher->name,
                            'qualification' => $teacher->qualification,
                            'experience' => $teacher->experience,
                            'profile_image' => $teacher->profile_image,
                            'status' => $teacher->status,
                        ]);
                    }

                    $override->order_no = $orderNo;
                    $override->save();
                    // ✅ ADD AUDIT LOG
                    AuditLogHelper::updated(
                        $override,
                        ['order_no' => $orderNo],
                        ['description' => "Teacher reordered to position {$orderNo}"]
                    );
                }
            });
            CacheHelper::forgetByTag('teachers');
            return ApiResponse::success([], 'Teachers order updated successfully');

        } catch (\Throwable $e) {
            return ApiResponse::exception($e);
        }
    }
}
