import { Link } from 'react-router-dom';
import { useEffect, useState } from 'react';
import { useRef } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { setPageTitle } from '../../store/themeConfigSlice';
import favicon from '../../assets/images/auth/fav_icon.png';
import logo from '../../assets/images/auth/logo.png';
import { Formik, Form, Field, ErrorMessage } from 'formik';
import * as Yup from 'yup';
import Swal from 'sweetalert2';
import Button from '../../components/Buttons';
import IconSave from '../../components/Icon/IconSave';
import { toast } from 'react-toastify';
import { useAuth } from '../../hooks/useAuth';
import config from '../../config';
import { settingsService } from '../../services/settingsService';
import { IRootState } from '../../store';

interface GeneralSettingsFormValues {
    title: string;
    mobile: string;
    email: string;
    website_url: string;
    address: string;
    gst_no: string;
    pan: string;
    bank_name: string;
    bank_branch: string;
    acc_holder_name: string;
    acc_number: string;
    ifc_code: string;
    logo: File | null;
    favicon: File | null;
}

const GeneralSettings = () => {
    const dispatch = useDispatch();
    const formikRef = useRef<any>(null);
    const { settings: globalSettings } = useAuth();
    // Directly subscribe to Redux store to get latest settings
    const reduxSettings = useSelector((state: IRootState) => state.settings.settings);
    const [isLoading, setIsLoading] = useState(false);
    const [logoPreview, setLogoPreview] = useState<string | null>(null);
    const [faviconPreview, setFaviconPreview] = useState<string | null>(null);
    const [initialLogoUrl, setInitialLogoUrl] = useState<string>('');
    const [initialFaviconUrl, setInitialFaviconUrl] = useState<string>('');

    useEffect(() => {
        dispatch(setPageTitle('General Settings'));
    }, [dispatch]);

    // Validation function for GST number
    const validateGST = (gst: string) => {
        const gstRegex = /^[0-9]{2}[A-Z]{5}[0-9]{4}[A-Z]{1}[1-9A-Z]{1}Z[0-9A-Z]{1}$/;
        return gstRegex.test(gst);
    };

    // Validation function for PAN number
    const validatePAN = (pan: string) => {
        const panRegex = /^[A-Z]{5}[0-9]{4}[A-Z]{1}$/;
        return panRegex.test(pan);
    };

    // Validation function for IFSC code
    const validateIFSC = (ifsc: string) => {
        const ifscRegex = /^[A-Z]{4}0[A-Z0-9]{6}$/;
        return ifscRegex.test(ifsc);
    };

    const validationSchema = Yup.object({
        title: Yup.string().required('Website title is required'),
        mobile: Yup.string()
            .required('Mobile number is required')
            .matches(/^[6-9]\d{9}$/, 'Enter a valid 10-digit mobile number'),
        email: Yup.string()
            .required('Email is required')
            .email('Enter a valid email address'),
        website_url: Yup.string()
            .required('Website URL is required')
            .url('Enter a valid URL (https://example.com)'),
        address: Yup.string().required('Address is required'),
        gst_no: Yup.string()
            .required('GSTIN number is required')
            .test('valid-gst', 'Enter a valid GSTIN number (format: 22AAAAA0000A1Z)', function(value) {
                if (!value) return false;
                return validateGST(value);
            }),
        pan: Yup.string()
            .required('PAN number is required')
            .test('valid-pan', 'Enter a valid PAN number (format: ABCDE1234F)', function(value) {
                if (!value) return false;
                return validatePAN(value);
            }),
        bank_name: Yup.string().required('Bank name is required'),
        bank_branch: Yup.string().required('Bank branch is required'),
        acc_holder_name: Yup.string().required('Account holder name is required'),
        acc_number: Yup.string()
            .required('Account number is required')
            .matches(/^[0-9]{9,18}$/, 'Account number should be 9-18 digits long'),
        ifc_code: Yup.string()
            .required('IFSC code is required')
            .test('valid-ifsc', 'Enter a valid IFSC code (format: SBIN0001234)', function(value) {
                if (!value) return false;
                return validateIFSC(value);
            }),
    });

    // Function to update UI from settings data
    const updateUIFromSettings = (data: any) => {
        if (!data) return;

        const storageBaseUrl = config.storageUrl;

        if (data.logo) {
            const logoUrl = data.logo.startsWith('http')
                ? data.logo
                : `${storageBaseUrl}/${data.logo}`;
            setInitialLogoUrl(logoUrl);
            setLogoPreview(logoUrl);
        } else {
            setInitialLogoUrl('');
            setLogoPreview(null);
        }

        if (data.favicon) {
            const faviconUrl = data.favicon.startsWith('http')
                ? data.favicon
                : `${storageBaseUrl}/${data.favicon}`;
            setInitialFaviconUrl(faviconUrl);
            setFaviconPreview(faviconUrl);
        } else {
            setInitialFaviconUrl('');
            setFaviconPreview(null);
        }

        // Update form values
        if (formikRef.current) {
            formikRef.current.setValues({
                title: data.title || '',
                mobile: data.mobile || '',
                email: data.email || '',
                website_url: data.website_url || '',
                address: data.address || '',
                gst_no: data.gst_no || '',
                pan: data.pan || '',
                bank_name: data.bank_name || '',
                bank_branch: data.bank_branch || '',
                acc_holder_name: data.acc_holder_name || '',
                acc_number: data.acc_number || '',
                ifc_code: data.ifc_code || '',
                logo: null,
                favicon: null,
            });
        }
    };

    const handleSubmit = async (values: GeneralSettingsFormValues) => {
        Swal.fire({
            icon: 'warning',
            text: 'Do you want to update general settings?',
            showCancelButton: true,
            confirmButtonText: 'Yes, Save',
            cancelButtonText: 'Cancel',
            padding: '2em',
            customClass: { popup: 'sweet-alerts' },
        }).then(async (result) => {
            if (!result.isConfirmed) return;

            setIsLoading(true);
            try {
                const formData = new FormData();

                formData.append('title', values.title);
                formData.append('mobile', values.mobile);
                formData.append('email', values.email);
                formData.append('website_url', values.website_url);
                formData.append('address', values.address);
                formData.append('gst_no', values.gst_no);
                formData.append('pan', values.pan);
                formData.append('bank_name', values.bank_name);
                formData.append('bank_branch', values.bank_branch);
                formData.append('acc_holder_name', values.acc_holder_name);
                formData.append('acc_number', values.acc_number);
                formData.append('ifc_code', values.ifc_code);

                if (values.logo && values.logo instanceof File) {
                    formData.append('logo', values.logo);
                }

                if (values.favicon && values.favicon instanceof File) {
                    formData.append('favicon', values.favicon);
                }

                // Use settingsService to update (this will fetch fresh settings)
                const response = await settingsService.updateSettings(formData);

                toast.success(response.message || 'Updated successfully');

                // Directly fetch fresh settings from API after update
                const freshSettings = await settingsService.fetchAndUpdateSettings();

                if (freshSettings) {
                    updateUIFromSettings(freshSettings);
                }

            } catch (err: any) {
                const response = err?.response?.data;

                if (response?.errors) {
                    Object.values(response.errors).forEach((fieldErrors: any) => {
                        fieldErrors.forEach((msg: string) => toast.error(msg));
                    });
                } else {
                    toast.error(response?.message || 'Update failed');
                }
            } finally {
                setIsLoading(false);
            }
        });
    };

    const fetchSettingsFromAPI = async () => {
        try {
            const fetchedSettings = await settingsService.fetchAndUpdateSettings();
            if (fetchedSettings) {
                updateUIFromSettings(fetchedSettings);
            }
        } catch (err) {
            console.error('Error fetching settings from API:', err);
        }
    };

    // Initial load - runs once on mount
    useEffect(() => {
        const initializeSettings = async () => {
            const data = reduxSettings || globalSettings;
            if (data && data.title) {
                updateUIFromSettings(data);
            } else {
                await fetchSettingsFromAPI();
            }
        };

        initializeSettings();

        return () => {
            if (logoPreview && logoPreview.startsWith('blob:')) {
                URL.revokeObjectURL(logoPreview);
            }
            if (faviconPreview && faviconPreview.startsWith('blob:')) {
                URL.revokeObjectURL(faviconPreview);
            }
        };
    }, []); // Empty dependency array - only run once

    // Watch for Redux settings changes and update UI
    useEffect(() => {
        if (reduxSettings && reduxSettings.title) {
            updateUIFromSettings(reduxSettings);
        }
    }, [reduxSettings]); // Re-run when reduxSettings changes

    const handleLogoChange = (e: React.ChangeEvent<HTMLInputElement>, setFieldValue: any) => {
        const file = e.target.files?.[0];
        if (!file) return;

        if (!file.type.startsWith('image/')) {
            toast.error('Please upload an image file');
            return;
        }

        if (file.size > 2 * 1024 * 1024) {
            toast.error('File size should be less than 2MB');
            return;
        }

        setFieldValue('logo', file);

        if (logoPreview && logoPreview.startsWith('blob:')) {
            URL.revokeObjectURL(logoPreview);
        }

        const previewUrl = URL.createObjectURL(file);
        setLogoPreview(previewUrl);
    };

    const handleFaviconChange = (e: React.ChangeEvent<HTMLInputElement>, setFieldValue: any) => {
        const file = e.target.files?.[0];
        if (!file) return;

        if (!file.type.startsWith('image/')) {
            toast.error('Please upload an image file');
            return;
        }

        if (file.size > 1 * 1024 * 1024) {
            toast.error('File size should be less than 1MB');
            return;
        }

        setFieldValue('favicon', file);

        if (faviconPreview && faviconPreview.startsWith('blob:')) {
            URL.revokeObjectURL(faviconPreview);
        }

        const previewUrl = URL.createObjectURL(file);
        setFaviconPreview(previewUrl);
    };

    const handleRemoveLogo = (setFieldValue: any) => {
        setFieldValue('logo', null);
        if (logoPreview && logoPreview.startsWith('blob:')) {
            URL.revokeObjectURL(logoPreview);
        }
        setLogoPreview(initialLogoUrl);
    };

    const handleRemoveFavicon = (setFieldValue: any) => {
        setFieldValue('favicon', null);
        if (faviconPreview && faviconPreview.startsWith('blob:')) {
            URL.revokeObjectURL(faviconPreview);
        }
        setFaviconPreview(initialFaviconUrl);
    };

    return (
        <div>
            <ul className="flex space-x-2 items-center">
                <li>
                    <Link to="/general_settings" className="text-primary text-lg hover:underline">
                        General Settings
                    </Link>
                </li>
                <li className="before:content-['/'] ml-2">
                    <span>Settings</span>
                </li>
            </ul>
            <div className="pt-6">
                <div className="grid grid-12 gap-6">
                    <div className="p-4 rounded-xl shadow-md bg-white">
                        <Formik
                            innerRef={formikRef}
                            initialValues={{
                                title: '',
                                mobile: '',
                                email: '',
                                website_url: '',
                                address: '',
                                gst_no: '',
                                pan: '',
                                bank_name: '',
                                bank_branch: '',
                                acc_holder_name: '',
                                acc_number: '',
                                ifc_code: '',
                                logo: null,
                                favicon: null,
                            }}
                            validationSchema={validationSchema}
                            onSubmit={handleSubmit}
                        >
                            {({ setFieldValue, values }) => (
                                <Form className="space-y-6">
                                    <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-5">
                                        <label className='text-xl text-primary col-span-full'>Basic Details</label>
                                        <div>
                                            <label className="block mb-1 font-medium text-black">Title<span className='text-danger'>*</span></label>
                                            <Field type="text" name="title" className="form-input" placeholder="Enter title" />
                                            <ErrorMessage name="title" component="div" className="text-danger mt-1" />
                                        </div>
                                        <div>
                                            <label className="block mb-1 font-medium text-black">Mobile Number<span className='text-danger'>*</span></label>
                                            <Field type="text" name="mobile" className="form-input" placeholder="Enter mobile number" />
                                            <ErrorMessage name="mobile" component="div" className="text-danger mt-1" />
                                        </div>
                                        <div>
                                            <label className="block mb-1 font-medium text-black">Email<span className='text-danger'>*</span></label>
                                            <Field type="email" name="email" className="form-input" placeholder="Enter email" />
                                            <ErrorMessage name="email" component="div" className="text-danger mt-1" />
                                        </div>
                                        <div>
                                            <label className="block mb-1 font-medium text-black">GSTIN No<span className='text-danger'>*</span></label>
                                            <Field type="text" name="gst_no" className="form-input uppercase" placeholder="Enter GSTIN No (22AAAAA0000A1Z)" />
                                            <ErrorMessage name="gst_no" component="div" className="text-danger mt-1" />
                                        </div>
                                        <div>
                                            <label className="block mb-1 font-medium text-black">PAN<span className='text-danger'>*</span></label>
                                            <Field type="text" name="pan" className="form-input uppercase" placeholder="Enter PAN No (ABCDE1234F)" />
                                            <ErrorMessage name="pan" component="div" className="text-danger mt-1" />
                                        </div>
                                        <div>
                                            <label className="block mb-1 font-medium text-black">Website URL<span className='text-danger'>*</span></label>
                                            <Field type="text" name="website_url" className="form-input" placeholder="https://example.com" />
                                            <ErrorMessage name="website_url" component="div" className="text-danger mt-1" />
                                        </div>
                                        <div className="lg:col-span-3">
                                            <label className="block mb-1 font-medium text-black">Address<span className='text-danger'>*</span></label>
                                            <Field as="textarea" name="address" rows="2" className="form-textarea" placeholder="Enter address" />
                                            <ErrorMessage name="address" component="div" className="text-danger mt-1" />
                                        </div>
                                    </div>

                                    <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
                                        <div>
                                            <label className="block mb-2 font-medium text-black">Logo</label>
                                            <div className="flex items-center gap-4">
                                                <div className="w-20 h-20 rounded-full overflow-hidden border bg-gray-100 flex items-center justify-center">
                                                    {logoPreview ? (
                                                        <img
                                                            src={logoPreview}
                                                            alt="logo"
                                                            className="w-full h-full object-cover"
                                                            onError={(e) => {
                                                                console.error('Logo failed to load:', logoPreview);
                                                                (e.target as HTMLImageElement).src = logo;
                                                            }}
                                                        />
                                                    ) : (
                                                        <img
                                                            src={logo}
                                                            alt="default logo"
                                                            className="w-full h-full object-cover"
                                                        />
                                                    )}
                                                </div>
                                                <div className="flex gap-2">
                                                    <label htmlFor="logo-upload" className="cursor-pointer px-4 py-1 bg-primary text-white rounded-md text-sm hover:opacity-90">
                                                        Upload
                                                    </label>
                                                    <input
                                                        id="logo-upload"
                                                        name="logo-upload"
                                                        type="file"
                                                        className="hidden"
                                                        accept="image/*"
                                                        onChange={(e) => handleLogoChange(e, setFieldValue)}
                                                        disabled={isLoading}
                                                    />
                                                    <button
                                                        type="button"
                                                        className="px-4 py-1 text-sm bg-red-500 text-white rounded-md hover:opacity-90"
                                                        onClick={() => handleRemoveLogo(setFieldValue)}
                                                        disabled={isLoading}
                                                    >
                                                        Remove
                                                    </button>
                                                </div>
                                            </div>
                                            {values.logo && (
                                                <p className="text-xs text-green-600 mt-1">
                                                    ✓ New logo selected: {(values.logo as File).name}
                                                </p>
                                            )}
                                        </div>
                                        <div>
                                            <label className="block mb-2 font-medium text-black">Favicon</label>
                                            <div className="flex items-center gap-4">
                                                <div className="w-16 h-16 rounded-md overflow-hidden border bg-gray-100 flex items-center justify-center">
                                                    {faviconPreview ? (
                                                        <img
                                                            src={faviconPreview}
                                                            alt="favicon"
                                                            className="w-full h-full object-cover"
                                                            onError={(e) => {
                                                                console.error('Favicon failed to load:', faviconPreview);
                                                                (e.target as HTMLImageElement).src = favicon;
                                                            }}
                                                        />
                                                    ) : (
                                                        <img
                                                            src={favicon}
                                                            alt="default favicon"
                                                            className="w-full h-full object-cover"
                                                        />
                                                    )}
                                                </div>
                                                <div className="flex gap-2">
                                                    <label htmlFor="favicon-upload" className="cursor-pointer px-4 py-1 bg-primary text-white rounded-md text-sm hover:opacity-90">
                                                        Upload
                                                    </label>
                                                    <input
                                                        id="favicon-upload"
                                                        name="favicon-upload"
                                                        type="file"
                                                        className="hidden"
                                                        accept="image/*"
                                                        onChange={(e) => handleFaviconChange(e, setFieldValue)}
                                                        disabled={isLoading}
                                                    />
                                                    <button
                                                        type="button"
                                                        className="px-4 py-1 text-sm bg-red-500 text-white rounded-md hover:opacity-90"
                                                        onClick={() => handleRemoveFavicon(setFieldValue)}
                                                        disabled={isLoading}
                                                    >
                                                        Remove
                                                    </button>
                                                </div>
                                            </div>
                                            {values.favicon && (
                                                <p className="text-xs text-green-600 mt-1">
                                                    ✓ New favicon selected: {(values.favicon as File).name}
                                                </p>
                                            )}
                                        </div>
                                    </div>

                                    <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-5">
                                        <label className='text-xl text-primary col-span-full'>Bank Details</label>
                                        <div>
                                            <label className="block mb-1 font-medium text-black">Bank Name<span className='text-danger'>*</span></label>
                                            <Field type="text" name="bank_name" className="form-input" placeholder="Enter bank name" />
                                            <ErrorMessage name="bank_name" component="div" className="text-danger mt-1" />
                                        </div>
                                        <div>
                                            <label className="block mb-1 font-medium text-black">Bank Branch<span className='text-danger'>*</span></label>
                                            <Field type="text" name="bank_branch" className="form-input" placeholder="Enter bank branch" />
                                            <ErrorMessage name="bank_branch" component="div" className="text-danger mt-1" />
                                        </div>
                                        <div>
                                            <label className="block mb-1 font-medium text-black">Account Holder Name<span className='text-danger'>*</span></label>
                                            <Field type="text" name="acc_holder_name" className="form-input" placeholder="Enter account holder name" />
                                            <ErrorMessage name="acc_holder_name" component="div" className="text-danger mt-1" />
                                        </div>
                                        <div>
                                            <label className="block mb-1 font-medium text-black">Account Number<span className='text-danger'>*</span></label>
                                            <Field type="text" name="acc_number" className="form-input" placeholder="Enter account number" />
                                            <ErrorMessage name="acc_number" component="div" className="text-danger mt-1" />
                                        </div>
                                        <div>
                                            <label className="block mb-1 font-medium text-black">IFSC Code<span className='text-danger'>*</span></label>
                                            <Field type="text" name="ifc_code" className="form-input uppercase" placeholder="Enter IFSC code (SBIN0001234)" />
                                            <ErrorMessage name="ifc_code" component="div" className="text-danger mt-1" />
                                        </div>
                                    </div>

                                    <div className='flex items-center justify-end'>
                                        <Button
                                            type="submit"
                                            variant="primary"
                                            icon={<IconSave />}
                                            iconPosition='left'
                                            disabled={isLoading}
                                        >
                                            {isLoading ? 'Saving...' : 'Save'}
                                        </Button>
                                    </div>
                                </Form>
                            )}
                        </Formik>
                    </div>
                </div>
            </div>
        </div>
    );
};

export default GeneralSettings;
