import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { useDispatch, useSelector } from 'react-redux';
import { loginSuccess, updateUser } from '../features/auth/authSlice';
import { useNavigate } from 'react-router-dom';
import axios from 'axios'; // ใช้ Axios ธรรมดาสำหรับการเรียกที่ยังไม่มี Token
import { addToast } from '../features/toast/toastSlice';
import axiosClient from "./axiosClient.js";

const API_BASE_URL = import.meta.env.VITE_API_BASE_URL;

// ----------------------------------------------------
// Helper Functions
// ----------------------------------------------------

/**
 * แปลง Object ให้เป็นฟอร์มข้อมูล (x-www-form-urlencoded)
 */
const toFormUrlEncoded = (data) => {
    // วนซ้ำ key และ encode
    return Object.keys(data)
        .map(key => {
            let value = data[key];
            // รับค่า remember_me (boolean) มาแปลงเป็น String 'true'
            if (value === true) {
                value = 'true';
            } else if (value === false) {
                value = 'false'; // หรือจะส่งเฉพาะเมื่อเป็น true ก็ได้
            }
            return encodeURIComponent(key) + '=' + encodeURIComponent(value);
        })
        .join('&');
};

/**
 * กำหนดบทบาท (Role) จาก Django User Object ที่สมบูรณ์
 * @param {object} user - User Object จาก /users/me/
 */
const determineRole = (user) => {
    if (!user || !user.id) {
        return 'guest';
    }

    // 1. ใช้ฟิลด์ 'role' ที่ส่งมาจาก Backend โดยตรง (ถ้ามี)
    if (user.role) {
        return user.role.toLowerCase(); // เช่น 'ADMIN' -> 'admin'
    }

    // 2. ใช้ฟิลด์ is_superuser/is_staff เป็น Fallback/เกณฑ์มาตรฐาน
    if (user.is_superuser) {
        return 'admin';
    }
    if (user.is_staff) {
        // ถ้าเป็น is_staff แต่ไม่ใช่ superuser
        return 'manager';
    }

    // ผู้ใช้ทั่วไป
    return 'viewer';
};


/**
 * ฟังก์ชันหลักในการล็อกอิน: ขั้นตอนที่ 1 (รับ Token) และ ขั้นตอนที่ 2 (รับ User Object)
 */
const loginUser = async (credentials) => {
    // credentials จะเป็น { username, password }
    const formData = toFormUrlEncoded(credentials);

    let access, refresh;

    // ---------------------------------------------
    // ขั้นตอนที่ 1: รับ Access/Refresh Token (POST /jwt/create/)
    // ---------------------------------------------
    try {
        const tokenResponse = await axios.post(`${API_BASE_URL}/api/v1/auth/jwt/create/`, formData, {
            headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
        });

        access = tokenResponse.data.access;
        refresh = tokenResponse.data.refresh;

    } catch (error) {
        // จัดการ Error จากการล็อกอิน
        const errorMessage = error.response?.data?.detail || "ชื่อผู้ใช้หรือรหัสผ่านไม่ถูกต้อง";
        throw new Error(errorMessage);
    }

    // ---------------------------------------------
    // ขั้นตอนที่ 2: ใช้ Access Token เพื่อดึง User Object (GET /users/me/)
    // ---------------------------------------------
    let user;
    try {
        const userResponse = await axios.get(`${API_BASE_URL}/api/v1/auth/users/me/`, {
            headers: {
                // ใช้ JWT เพื่อยืนยันตัวตน
                'Authorization': `Bearer ${access}`,
            },
        });

        user = userResponse.data;

    } catch (error) {
        console.error("Failed to fetch user data after token creation:", error);
        throw new Error("ล็อกอินสำเร็จ แต่ไม่สามารถดึงข้อมูลผู้ใช้ได้ (กรุณาติดต่อผู้ดูแลระบบ)");
    }

    // ---------------------------------------------
    // ขั้นตอนที่ 3: คำนวณ Role และส่งกลับข้อมูล
    // ---------------------------------------------
    const userRole = determineRole(user);

    return {
        access_token: access,
        refresh_token: refresh,
        user: user,
        role: userRole,
    };
};


// ----------------------------------------------------
// Custom Hook สำหรับจัดการการล็อกอิน
// ----------------------------------------------------
export const useLoginMutation = () => {
    const dispatch = useDispatch();
    const navigate = useNavigate();
    const queryClient = useQueryClient();

    return useMutation({
        mutationFn: loginUser,
        onSuccess: (data) => {

            // 1. จัดการ Token และ User Data
            localStorage.setItem('token', data.access_token);
            // บันทึก Refresh Token แยกต่างหาก
            localStorage.setItem('refresh_token', data.refresh_token);
            localStorage.setItem('user', JSON.stringify(data.user));
            localStorage.setItem('role', data.role); // บันทึก Role ที่ถูกต้อง

            // 2. อัปเดต Redux State
            dispatch(loginSuccess({ user: data.user, role: data.role }));

            // 3. นำทางผู้ใช้
            navigate('/dashboard', { replace: true });
            // Invalidating Query ที่เกี่ยวข้อง
            queryClient.invalidateQueries({ queryKey: ['userData'] });
            queryClient.invalidateQueries({ queryKey: ['userProfile'] });
            queryClient.invalidateQueries({ queryKey: ['modelList'] });
        },
        onError: (error) => {
            // error.message ถูกโยนมาจาก loginUser function
            console.error('Login API Error:', error.message);
            throw new Error(error.message);
        },
    });
};

// ----------------------------------------------------
// Helper Function: Registration API Call
// ----------------------------------------------------
const registerNewUser = async (userData) => {
    // Djoser Endpoint: POST /api/v1/auth/users/ (รับ username, email, password, phone_number)
    // Djoser /users/ Endpoint รับ JSON Body ได้โดยตรง (ไม่ใช้ x-www-form-urlencoded)

    // ลบ confirm_password ออกจาก payload ก่อนส่ง
    // ใช้ _ นำหน้าเพื่อบอก ESLint ว่าตัวแปรนี้จะไม่ถูกใช้
    // ต้องการ confirm_password เพื่อให้ Yup (Validation) ทำงาน แต่เราไม่ต้องการส่งมันไปยัง API Backend (เพราะ Djoser API ไม่ได้รับ Field นี้)
    const { confirm_password: _, ...payload } = userData;

    try {
        const response = await axios.post(`${API_BASE_URL}/api/v1/auth/users/`, payload);
        return response.data;

    } catch (error) {
        // จัดการ Error เช่น Username/Email ซ้ำ
        const errorDetail = error.response?.data;
        let errorMessage = "การลงทะเบียนล้มเหลว โปรดตรวจสอบข้อมูลอีกครั้ง";

        if (errorDetail) {
            if (errorDetail.username) errorMessage = `ชื่อผู้ใช้งาน: ${errorDetail.username[0]}`;
            else if (errorDetail.email) errorMessage = `อีเมล: ${errorDetail.email[0]}`;
            else if (errorDetail.phone_number) errorMessage = `เบอร์โทรศัพท์: ${errorDetail.phone_number[0]}`;
        }

        throw new Error(errorMessage);
    }
};

// ----------------------------------------------------
// Custom Hook สำหรับจัดการการลงทะเบียน
// ----------------------------------------------------
export const useRegisterMutation = () => {
    const dispatch = useDispatch();
    const navigate = useNavigate();

    return useMutation({
        mutationFn: registerNewUser,
        onSuccess: () => {
            dispatch(addToast({ message: 'ลงทะเบียนสำเร็จ! คุณสามารถเข้าสู่ระบบได้ทันที', type: 'success' }));
            navigate('/login');
        },
        onError: (error) => {
            // ส่ง Toast แจ้งเตือนข้อผิดพลาดที่โยนมาจาก registerNewUser
            dispatch(addToast({ message: `ลงทะเบียนล้มเหลว: ${error.message}`, type: 'error' }));
            throw new Error(error.message);
        },
    });
};

// ----------------------------------------------------
// Hook สำหรับส่งคำขอรีเซ็ตรหัสผ่าน (ขั้นตอน A)
// ----------------------------------------------------
export const useRequestPasswordReset = () => {
    const dispatch = useDispatch();

    return useMutation({
        mutationFn: async ({ email }) => {
            // Djoser Endpoint: รับ email/username เพื่อส่งอีเมล
            const response = await axios.post(
                `${API_BASE_URL}/api/v1/auth/users/reset_password/`,
                { email: email } // Djoser รับ JSON Body
            );
            return response.data;
        },
        onSuccess: () => {
            dispatch(addToast({
                message: 'คำขอรีเซ็ตถูกส่งไปยังอีเมลของคุณแล้ว',
                type: 'success'
            }));
        },
        onError: (error) => {
            const msg = error.response?.data?.detail || 'ไม่พบผู้ใช้งานด้วยอีเมลนี้';
            dispatch(addToast({ message: `ล้มเหลว: ${msg}`, type: 'error' }));
            throw new Error(msg);
        },
    });
};


// ----------------------------------------------------
// Hook สำหรับยืนยันและตั้งรหัสผ่านใหม่ (ขั้นตอน B)
// ----------------------------------------------------
export const useConfirmPasswordReset = () => {
    const dispatch = useDispatch();
    const navigate = useNavigate();

    return useMutation({
        mutationFn: async (data) => {
            // Djoser Endpoint: รับ uid, token, new_password
            const response = await axios.post(
                `${API_BASE_URL}/api/v1/auth/users/reset_password_confirm/`,
                data
            );
            return response.data;
        },
        onSuccess: () => {
            dispatch(addToast({
                message: 'รหัสผ่านถูกตั้งค่าใหม่เรียบร้อยแล้ว!',
                type: 'success'
            }));
            navigate('/login', { replace: true });
        },
        onError: (error) => {
            const msg = error.response?.data?.detail || 'ลิงก์ไม่ถูกต้องหรือหมดอายุ';
            dispatch(addToast({ message: `ตั้งรหัสผ่านใหม่ล้มเหลว: ${msg}`, type: 'error' }));
            throw new Error(msg);
        },
    });
};

/**
 * ฟังก์ชันสำหรับเรียก API เพื่อต่ออายุ Access Token ด้วย Refresh Token
 */
export const refreshAccessToken = async () => {
    const refresh = localStorage.getItem('refresh_token'); // เก็บ Refresh Token แยกต่างหาก

    if (!refresh) {
        throw new Error("Refresh token not found.");
    }

    const response = await axios.post(`${API_BASE_URL}/api/v1/auth/jwt/refresh/`, {
        refresh: refresh,
    });

    // คืนค่า Access Token ใหม่
    return response.data.access;
};

// ----------------------------------------------------
// Hook ดึงข้อมูลผู้ใช้ปัจจุบัน (GET /users/me/)
// ----------------------------------------------------
export const useUserQuery = () => {
    // ดึงสถานะปัจจุบันของ User จาก Redux Store
    const userId = useSelector(state => state.auth.user?.id);
    const isAuthenticated = useSelector(state => state.auth.isAuthenticated);

    return useQuery({
        // ทำให้ Query Key ขึ้นอยู่กับ User ID
        queryKey: ['userProfile', userId],

        // ไม่รัน Query ถ้าผู้ใช้ไม่ได้ล็อกอิน
        enabled: isAuthenticated && !!userId,

        queryFn: async () => {
            const response = await axiosClient.get(`${API_BASE_URL}/api/v1/auth/users/me/`);
            return response.data;
        },
        staleTime: 60000,
    });
};

// ----------------------------------------------------
// Hook อัปเดตข้อมูลผู้ใช้ (PATCH /users/me/)
// ----------------------------------------------------
export const useUpdateProfileMutation = () => {
    const queryClient = useQueryClient();
    const dispatch = useDispatch();

    return useMutation({
        mutationFn: async (profileData) => {
            // Djoser Endpoint: PATCH /users/me/
            const response = await axiosClient.patch(`${API_BASE_URL}/api/v1/auth/users/me/`, profileData);
            return response.data;
        },
        onSuccess: (updatedUser) => {
            dispatch(addToast({ message: 'แก้ไขข้อมูลส่วนตัวสำเร็จแล้ว!', type: 'success' }));

            // อัปเดต Redux Store และ Local Storage ทันที
            const newRole = determineRole(updatedUser);
            dispatch(updateUser({ user: updatedUser, role: newRole }));

            // Invalidate Query เพื่อดึงข้อมูล Profile ใหม่
            queryClient.invalidateQueries({ queryKey: ['userProfile'] });
        },
        onError: (error) => {
            const msg = error.response?.data?.email || error.response?.data?.detail || 'การอัปเดตล้มเหลว';
            dispatch(addToast({ message: `อัปเดต Profile ล้มเหลว: ${msg}`, type: 'error' }));
        },
    });
};