import { useEffect, useState } from 'react';
import {
    Avatar,
    Button,
    Col,
    Form,
    Input,
    Row,
    Spin,
    Upload,
    message,
} from 'antd';
import {
    UserOutlined,
    UploadOutlined,
    SaveOutlined,
} from '@ant-design/icons';
import ImgCrop from 'antd-img-crop';
import type { RcFile } from 'antd/es/upload/interface';
import { AppContainer } from '../../components/AppContainer';
import jwtAxios from '../../api/axiosInstance';
import { ENDPOINTS } from '../../api/endpoints';
import { useAppDispatch } from '../../redux/hooks';
import { updateUser } from '../../redux/slices/authSlice';

interface ProfileData {
    id: string;
    name: string;
    email: string;
    mobileNo: string | null;
    roleId: string;
    status: boolean;
    profile: string | null;
    profileUrl: string | null;
    role?: {
        id: string;
        name: string;
    };
}

const Profile = () => {
    const dispatch = useAppDispatch();
    const [form] = Form.useForm();
    const [loading, setLoading] = useState(false);
    const [profileData, setProfileData] = useState<ProfileData | null>(null);
    const [avatarPreview, setAvatarPreview] = useState<string | null>(null);
    const [fileToUpload, setFileToUpload] = useState<RcFile | null>(null);

    // -----------------------------
    // Fetch current logged-in user's profile — GET ENDPOINTS.PROFILE
    // -----------------------------
    const fetchProfile = async () => {
        setLoading(true);
        try {
            const res = await jwtAxios.get(ENDPOINTS.PROFILE);
            // Adjust this line if your response is wrapped differently
            // (e.g. res.data.result instead of res.data directly).
            const record: ProfileData = res.data?.result ?? res.data;

            setProfileData(record);
            setAvatarPreview(record.profileUrl || null);

            form.setFieldsValue({
                name: record.name,
                email: record.email,
                mobileNo: record.mobileNo,
            });
        } catch (err: any) {
            message.error(err.response?.data?.message || 'Failed to load profile');
        } finally {
            setLoading(false);
        }
    };

    useEffect(() => {
        fetchProfile();
    }, []);

    // -----------------------------
    // Image select — just preview + hold the file, don't auto-upload.
    // Actual upload happens on form submit, bundled with the rest of
    // the payload via FormData.
    // -----------------------------
    const handleBeforeUpload = (file: RcFile) => {
        const isImage = file.type.startsWith('image/');
        if (!isImage) {
            message.error('You can only upload image files');
            return Upload.LIST_IGNORE;
        }

        const isLt2M = file.size / 1024 / 1024 < 2;
        if (!isLt2M) {
            message.error('Image must be smaller than 2MB');
            return Upload.LIST_IGNORE;
        }

        setFileToUpload(file);
        setAvatarPreview(URL.createObjectURL(file));
        return false; // prevent antd's default auto-upload behavior
    };

    // -----------------------------
    // Submit — only include fields the user actually changed:
    // - name, mobileNo: always sent (current form values)
    // - password: only sent if the user typed a new one
    // - profile: only sent if a new image was selected
    // Uses FormData since we may be sending a file.
    // -----------------------------
    const handleSubmit = async (values: any) => {
        setLoading(true);

        try {
            const formData = new FormData();
            formData.append('name', values.name);
            formData.append('mobileNo', values.mobileNo || '');

            if (values.password) {
                formData.append('password', values.password);
            }

            if (fileToUpload) {
                formData.append('profile', fileToUpload);
            }

            const res = await jwtAxios.put(ENDPOINTS.PROFILE, formData, {
                headers: { 'Content-Type': 'multipart/form-data' },
            });

            // Update user in Redux so header/dashboard reflects immediately
            dispatch(updateUser(res.data));

            message.success(res.data?.message || 'Profile updated successfully');

            // Clear password fields after a successful update, keep everything else
            form.setFieldsValue({ password: undefined, confirmPassword: undefined });
            setFileToUpload(null);

            fetchProfile(); // refresh with the latest saved data (e.g. new profileUrl)
        } catch (err: any) {
            const responseData = err.response?.data;
            const fieldErrors = responseData?.errors;

            if (fieldErrors && typeof fieldErrors === 'object') {
                form.setFields(
                    Object.entries(fieldErrors).map(([name, error]) => ({
                        name,
                        errors: [String(error)],
                    }))
                );
                message.error(responseData?.message || 'Please fix the highlighted fields');
            } else {
                message.error(responseData?.message || 'Failed to update profile');
            }
        } finally {
            setLoading(false);
        }
    };

    return (
        <div>
            <Spin spinning={loading}>
                <AppContainer title="My Profile">
                    <div className='grid md:grid-cols-2 grid-cols-1'>
                        {/* Avatar Section */}
                        <div className="flex flex-col items-center border-b border-gray-200 p-8">
                            <Avatar
                                size={100}
                                icon={<UserOutlined />}
                                src={avatarPreview}
                                className="bg-green-600 mb-3"
                            />
                            <ImgCrop
                                rotationSlider
                                aspect={1}          // 1:1 square
                                quality={1}
                                modalTitle="Crop Profile Photo"
                                modalOk="Save"
                                modalCancel="Cancel"
                            >
                                <Upload
                                    accept="image/*"
                                    showUploadList={false}
                                    beforeUpload={handleBeforeUpload}
                                >
                                    <Button className='m-5!'
                                        icon={<UploadOutlined />}>Change Photo</Button>
                                </Upload>
                            </ImgCrop>
                            <div className='flex justify-center w-full'>
                                <span className='text-gray-400 text-xs'>*Image must be smaller than 2MB and must be a JPEG, PNG file.</span>
                            </div>
                            <div className='flex justify-center w-full'>
                                {profileData?.role?.name && (
                                    <span className="mt-2 text-xs font-medium uppercase tracking-wide text-green-700 bg-green-100 px-2 py-0.5 rounded-full">
                                        {profileData.role.name}
                                    </span>
                                )}
                            </div>
                        </div>

                        {/* Form Section */}
                        <Form form={form} layout="vertical" onFinish={handleSubmit}>
                            <Row gutter={16}>
                                <Col xs={24} sm={12}>
                                    <Form.Item label="Name" name="name" rules={[{ required: true }]}>
                                        <Input />
                                    </Form.Item>
                                </Col>

                                <Col xs={24} sm={12}>
                                    <Form.Item label="Email" name="email">
                                        <Input disabled />
                                    </Form.Item>
                                </Col>

                                <Col xs={24} sm={12}>
                                    <Form.Item
                                        label="Mobile No"
                                        name="mobileNo"
                                        rules={[
                                            {
                                                pattern: /^[0-9]{10}$/,
                                                message: 'Enter a valid 10-digit mobile number',
                                            },
                                        ]}
                                    >
                                        <Input maxLength={10} />
                                    </Form.Item>
                                </Col>

                                <Col xs={24} sm={12}>
                                    <Form.Item
                                        label="New Password"
                                        name="password"
                                        rules={[{ min: 8, message: 'Password must be at least 8 characters' }]}
                                        extra="Leave blank to keep your current password"
                                    >
                                        <Input.Password autoComplete="new-password" />
                                    </Form.Item>
                                </Col>

                                <Col xs={24} sm={12}>
                                    <Form.Item
                                        label="Confirm New Password"
                                        name="confirmPassword"
                                        dependencies={['password']}
                                        rules={[
                                            ({ getFieldValue }) => ({
                                                validator(_, value) {
                                                    const password = getFieldValue('password');

                                                    if (!password && !value) {
                                                        return Promise.resolve();
                                                    }
                                                    if (password && !value) {
                                                        return Promise.reject(new Error('Please confirm your new password'));
                                                    }
                                                    if (password === value) {
                                                        return Promise.resolve();
                                                    }
                                                    return Promise.reject(new Error('Passwords do not match'));
                                                },
                                            }),
                                        ]}
                                    >
                                        <Input.Password autoComplete="new-password" />
                                    </Form.Item>
                                </Col>
                            </Row>

                            <div className="flex justify-end mt-2">
                                <Button
                                    type="primary"
                                    htmlType="submit"
                                    icon={<SaveOutlined />}
                                    className="bg-green-600"
                                    loading={loading}
                                >
                                    Save Changes
                                </Button>
                            </div>
                        </Form>
                    </div>
                </AppContainer>
            </Spin>
        </div>
    );
};

export default Profile;