import { create } from 'zustand';

const MAX_HISTORY = 50;

const defaultPageSettings = {
    backgroundColor: '#f0f0f1',
    backgroundType: 'color',
    backgroundImage: '',
    backgroundGradient: { color1: '#667eea', color2: '#764ba2', angle: 135 },
    backgroundOverlay: { color: '#000000', opacity: 0 },
    backgroundPosition: 'center',
    backgroundSize: 'cover',
    overlayEnabled: false,
    overlayColor: '#000000',
    overlayOpacity: 0.4,
    pageAnimation: { type: 'none', duration: 600 },
    animatedGradient: { colors: ['#667eea', '#764ba2'], angle: 135, speed: 8 },
    customCss: '',
};

const defaultLoginFormBlock = {
    id: 'loginform-1',
    type: 'loginForm',
    order: 1,
    settings: {
        formBackground: '#ffffff',
        formBorderRadius: 8,
        formPadding: 30,
        formWidth: 360,
        formBoxShadow: 'soft',
        formBorderEnabled: false,
        formBorderColor: '#e0e0e0',
        formBorderWidth: 1,
        animationType: 'none',
        animationDuration: 'normal',
        usernameLabel: 'Username or Email Address',
        usernameShowLabel: true,
        usernamePlaceholder: '',
        usernameBackgroundColor: '#ffffff',
        usernameBorderColor: '#d1d5db',
        usernameBorderRadius: 6,
        usernameTextColor: '#1f2937',
        usernameFontSize: 15,
        usernameHeight: 44,
        passwordLabel: 'Password',
        passwordShowLabel: true,
        passwordPlaceholder: '',
        passwordBackgroundColor: '#ffffff',
        passwordBorderColor: '#d1d5db',
        passwordBorderRadius: 6,
        passwordTextColor: '#1f2937',
        passwordFontSize: 15,
        passwordHeight: 44,
        showPasswordToggle: false,
        submitText: 'Log In',
        submitBackgroundColor: '#2271b1',
        submitTextColor: '#ffffff',
        submitHoverBackgroundColor: '#135e96',
        submitBorderRadius: 6,
        submitHeight: 44,
        submitFontSize: 15,
        submitFontWeight: '600',
        submitFullWidth: true,
        hoverEffect: 'none',
        showLoadingSpinner: false,
        shadowX: 0,
        shadowY: 20,
        shadowBlur: 40,
        shadowSpread: 0,
        shadowColor: 'rgba(0,0,0,0.15)',
        shadowInset: false,
        showRememberMe: true,
        rememberMeText: 'Remember Me',
        showLostPassword: true,
        lostPasswordText: 'Lost your password?',
        lostPasswordColor: '#2271b1',
        showBackLink: true,
        showRegisterLink: true,
    },
};

const createBlankTemplate = () => ({
    pageSettings: { ...defaultPageSettings },
    blocks: [{ ...defaultLoginFormBlock, settings: { ...defaultLoginFormBlock.settings } }],
});

const useEditorStore = create((set, get) => ({
    // State.
    mode: 'gallery',
    templates: [],
    selectedTemplateId: null,
    activeTemplateId: null,
    editingTemplate: null,
    selectedBlockId: null,
    inspectorTab: 'block',
    devicePreview: 'desktop',
    sidebarOpen: true,
    isDirty: false,
    history: [],
    historyIndex: -1,
    isSaving: false,
    notices: [],
    searchQuery: '',
    categoryFilter: 'all',
    isLoading: true,

    // Actions.
    setMode: (mode) => set({ mode }),
    setSearchQuery: (searchQuery) => set({ searchQuery }),
    setCategoryFilter: (categoryFilter) => set({ categoryFilter }),
    setDevicePreview: (devicePreview) => set({ devicePreview }),
    toggleSidebar: () => set((state) => ({ sidebarOpen: !state.sidebarOpen })),
    setInspectorTab: (inspectorTab) => set({ inspectorTab }),
    setSelectedBlockId: (selectedBlockId) => set({ selectedBlockId, inspectorTab: 'block' }),

    addNotice: (msg, type = 'success') => {
        const id = Date.now();
        set((state) => ({ notices: [...state.notices, { id, msg, type }] }));
        setTimeout(() => {
            set((state) => ({ notices: state.notices.filter((n) => n.id !== id) }));
        }, 4000);
    },

    // Fetch templates from REST API.
    fetchTemplates: async () => {
        set({ isLoading: true });
        try {
            const res = await fetch(`${window.lpcdEditor.restUrl}templates`, {
                headers: { 'X-WP-Nonce': window.lpcdEditor.nonce },
            });
            const data = await res.json();
            const active = data.find((t) => t.isActive);
            set({
                templates: data,
                activeTemplateId: active ? active.id : null,
                selectedTemplateId: active ? active.id : (data.length > 0 ? data[0].id : null),
                isLoading: false,
            });
        } catch {
            set({ isLoading: false });
            get().addNotice('Failed to load templates.', 'error');
        }
    },

    // Select a template for preview.
    selectTemplate: (id) => set({ selectedTemplateId: id }),

    // Activate a template.
    activateTemplate: async (id) => {
        try {
            const res = await fetch(`${window.lpcdEditor.restUrl}templates/${id}/activate`, {
                method: 'POST',
                headers: {
                    'X-WP-Nonce': window.lpcdEditor.nonce,
                    'Content-Type': 'application/json',
                },
            });
            if (res.ok) {
                set((state) => ({
                    activeTemplateId: id,
                    templates: state.templates.map((t) => ({
                        ...t,
                        isActive: t.id === id,
                    })),
                }));
                get().addNotice('Template activated!', 'success');
            }
        } catch {
            get().addNotice('Failed to activate template.', 'error');
        }
    },

    // Enter block editor mode.
    enterEditor: async (templateId) => {
        try {
            const res = await fetch(`${window.lpcdEditor.restUrl}templates/${templateId}`, {
                headers: { 'X-WP-Nonce': window.lpcdEditor.nonce },
            });
            const template = await res.json();

            const draftKey = `lpcd_draft_${templateId}`;
            const savedDraft = localStorage.getItem(draftKey);
            let jsonData = template.jsonData;

            if (savedDraft) {
                try {
                    const parsed = JSON.parse(savedDraft);
                    // Show restore banner via state.
                    set({
                        mode: 'editor',
                        editingTemplate: {
                            id: template.id,
                            name: template.name,
                            type: template.type,
                            jsonData: parsed,
                        },
                        selectedBlockId: null,
                        isDirty: true,
                        history: [JSON.stringify(parsed)],
                        historyIndex: 0,
                        hasDraft: true,
                        draftOriginal: jsonData,
                    });
                    return;
                } catch { /* ignore bad drafts */ }
            }

            set({
                mode: 'editor',
                editingTemplate: {
                    id: template.id,
                    name: template.name,
                    type: template.type,
                    jsonData,
                },
                selectedBlockId: null,
                isDirty: false,
                history: [JSON.stringify(jsonData)],
                historyIndex: 0,
                hasDraft: false,
                draftOriginal: null,
            });
        } catch {
            get().addNotice('Failed to load template data.', 'error');
        }
    },

    // Discard draft.
    discardDraft: () => {
        const state = get();
        if (state.draftOriginal && state.editingTemplate) {
            const id = state.editingTemplate.id;
            localStorage.removeItem(`lpcd_draft_${id}`);
            set({
                editingTemplate: {
                    ...state.editingTemplate,
                    jsonData: state.draftOriginal,
                },
                isDirty: false,
                history: [JSON.stringify(state.draftOriginal)],
                historyIndex: 0,
                hasDraft: false,
                draftOriginal: null,
            });
        }
    },

    // Exit editor mode.
    exitEditor: () => {
        set({
            mode: 'gallery',
            editingTemplate: null,
            selectedBlockId: null,
            isDirty: false,
            history: [],
            historyIndex: -1,
            hasDraft: false,
            draftOriginal: null,
        });
    },

    // Push state to history.
    pushHistory: (jsonData) => {
        set((state) => {
            const newHistory = state.history.slice(0, state.historyIndex + 1);
            newHistory.push(JSON.stringify(jsonData));
            if (newHistory.length > MAX_HISTORY) {
                newHistory.shift();
            }
            return {
                history: newHistory,
                historyIndex: newHistory.length - 1,
            };
        });
    },

    // Update editing template data.
    updateEditingTemplate: (jsonData) => {
        set((state) => {
            if (!state.editingTemplate) return {};
            const updated = { ...state.editingTemplate, jsonData };
            // Save draft to localStorage.
            try {
                localStorage.setItem(`lpcd_draft_${state.editingTemplate.id}`, JSON.stringify(jsonData));
            } catch { /* quota exceeded */ }
            return { editingTemplate: updated, isDirty: true };
        });
        get().pushHistory(jsonData);
    },

    // Update template name.
    updateTemplateName: (name) => {
        set((state) => {
            if (!state.editingTemplate) return {};
            return {
                editingTemplate: { ...state.editingTemplate, name },
                isDirty: true,
            };
        });
    },

    // Update page settings.
    updatePageSettings: (key, value) => {
        const state = get();
        if (!state.editingTemplate) return;
        const newJsonData = {
            ...state.editingTemplate.jsonData,
            pageSettings: {
                ...state.editingTemplate.jsonData.pageSettings,
                [key]: value,
            },
        };
        get().updateEditingTemplate(newJsonData);
    },

    // Update nested page setting (e.g., backgroundGradient.color1).
    updateNestedPageSetting: (parent, key, value) => {
        const state = get();
        if (!state.editingTemplate) return;
        const current = state.editingTemplate.jsonData.pageSettings[parent] || {};
        const newJsonData = {
            ...state.editingTemplate.jsonData,
            pageSettings: {
                ...state.editingTemplate.jsonData.pageSettings,
                [parent]: { ...current, [key]: value },
            },
        };
        get().updateEditingTemplate(newJsonData);
    },

    // Update a specific block's settings.
    updateBlockSettings: (blockId, key, value) => {
        const state = get();
        if (!state.editingTemplate) return;
        const blocks = state.editingTemplate.jsonData.blocks.map((block) => {
            if (block.id === blockId) {
                return {
                    ...block,
                    settings: { ...block.settings, [key]: value },
                };
            }
            return block;
        });
        const newJsonData = { ...state.editingTemplate.jsonData, blocks };
        get().updateEditingTemplate(newJsonData);
    },

    // Add a block.
    addBlock: (type) => {
        const state = get();
        if (!state.editingTemplate) return;

        const blocks = state.editingTemplate.jsonData.blocks;

        // Only one loginForm allowed.
        if (type === 'loginForm' && blocks.some((b) => b.type === 'loginForm')) {
            get().addNotice('Only one login form block is allowed.', 'error');
            return;
        }

        // Only one videoBackground allowed.
        if (type === 'videoBackground' && blocks.some((b) => b.type === 'videoBackground')) {
            get().addNotice('Only one video background block is allowed.', 'error');
            return;
        }

        const maxOrder = blocks.reduce((max, b) => Math.max(max, b.order || 0), 0);
        const newBlock = {
            id: `block-${Date.now()}`,
            type,
            order: maxOrder + 1,
            panel: type === 'loginForm' ? 'form' : 'branding',
            settings: getDefaultBlockSettings(type),
        };

        const newBlocks = [...blocks, newBlock];
        const newJsonData = { ...state.editingTemplate.jsonData, blocks: newBlocks };
        get().updateEditingTemplate(newJsonData);
        set({ selectedBlockId: newBlock.id });
    },

    // Remove a block.
    removeBlock: (blockId) => {
        const state = get();
        if (!state.editingTemplate) return;
        const blocks = state.editingTemplate.jsonData.blocks.filter((b) => b.id !== blockId);
        const newJsonData = { ...state.editingTemplate.jsonData, blocks };
        get().updateEditingTemplate(newJsonData);
        if (state.selectedBlockId === blockId) {
            set({ selectedBlockId: null });
        }
    },

    // Duplicate a block.
    duplicateBlock: (blockId) => {
        const state = get();
        if (!state.editingTemplate) return;
        const blocks = state.editingTemplate.jsonData.blocks;
        const block = blocks.find((b) => b.id === blockId);
        if (!block) return;

        if (block.type === 'loginForm') {
            get().addNotice('Only one login form block is allowed.', 'error');
            return;
        }

        const maxOrder = blocks.reduce((max, b) => Math.max(max, b.order || 0), 0);
        const newBlock = {
            ...JSON.parse(JSON.stringify(block)),
            id: `block-${Date.now()}`,
            order: maxOrder + 1,
        };
        const newBlocks = [...blocks, newBlock];
        const newJsonData = { ...state.editingTemplate.jsonData, blocks: newBlocks };
        get().updateEditingTemplate(newJsonData);
        set({ selectedBlockId: newBlock.id });
    },

    // Reorder blocks.
    reorderBlocks: (newBlocks) => {
        const state = get();
        if (!state.editingTemplate) return;
        const reordered = newBlocks.map((b, i) => ({ ...b, order: i + 1 }));
        const newJsonData = { ...state.editingTemplate.jsonData, blocks: reordered };
        get().updateEditingTemplate(newJsonData);
    },

    // Move block up/down.
    moveBlock: (blockId, direction) => {
        const state = get();
        if (!state.editingTemplate) return;
        const blocks = [...state.editingTemplate.jsonData.blocks].sort((a, b) => a.order - b.order);
        const index = blocks.findIndex((b) => b.id === blockId);
        if (index === -1) return;

        const newIndex = direction === 'up' ? index - 1 : index + 1;
        if (newIndex < 0 || newIndex >= blocks.length) return;

        const temp = blocks[index];
        blocks[index] = blocks[newIndex];
        blocks[newIndex] = temp;

        get().reorderBlocks(blocks);
    },

    // Switch block between branding and form panels.
    switchBlockPanel: (blockId) => {
        const state = get();
        if (!state.editingTemplate) return;
        const blocks = state.editingTemplate.jsonData.blocks.map((b) => {
            if (b.id === blockId) {
                return { ...b, panel: b.panel === 'form' ? 'branding' : 'form' };
            }
            return b;
        });
        const newJsonData = { ...state.editingTemplate.jsonData, blocks };
        get().updateEditingTemplate(newJsonData);
    },

    // Undo.
    undo: () => {
        set((state) => {
            if (state.historyIndex <= 0) return {};
            const newIndex = state.historyIndex - 1;
            const data = JSON.parse(state.history[newIndex]);
            return {
                historyIndex: newIndex,
                editingTemplate: { ...state.editingTemplate, jsonData: data },
                isDirty: true,
            };
        });
    },

    // Redo.
    redo: () => {
        set((state) => {
            if (state.historyIndex >= state.history.length - 1) return {};
            const newIndex = state.historyIndex + 1;
            const data = JSON.parse(state.history[newIndex]);
            return {
                historyIndex: newIndex,
                editingTemplate: { ...state.editingTemplate, jsonData: data },
                isDirty: true,
            };
        });
    },

    // Save template.
    saveTemplate: async (activate = false) => {
        const state = get();
        if (!state.editingTemplate || state.isSaving) return;

        set({ isSaving: true });

        try {
            const { id, name, type, jsonData } = state.editingTemplate;
            let url, method;

            if (id) {
                url = `${window.lpcdEditor.restUrl}templates/${id}`;
                method = 'PUT';
            } else {
                url = `${window.lpcdEditor.restUrl}templates`;
                method = 'POST';
            }

            const res = await fetch(url, {
                method,
                headers: {
                    'X-WP-Nonce': window.lpcdEditor.nonce,
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({ name, jsonData }),
            });

            const result = await res.json();

            if (!res.ok) {
                throw new Error(result.message || 'Failed to save.');
            }

            const templateId = id || result.id;

            // Clear draft.
            localStorage.removeItem(`lpcd_draft_${templateId}`);

            if (activate) {
                await get().activateTemplate(templateId);
            }

            set({ isDirty: false, isSaving: false });
            get().addNotice(activate ? 'Published & Activated!' : 'Saved!', 'success');

            // Refresh templates.
            get().fetchTemplates();
        } catch (err) {
            set({ isSaving: false });
            get().addNotice(err.message || 'Save failed.', 'error');
        }
    },

    // Reset template.
    resetTemplate: async (id) => {
        if (
            !window.confirm(
                'Are you sure you want to reset this template to its original state? This will lose all your changes for this template.'
            )
        )
            return;

        try {
            const res = await fetch(`${window.lpcdEditor.restUrl}templates/${id}/reset`, {
                method: 'POST',
                headers: {
                    'X-WP-Nonce': window.lpcdEditor.nonce,
                    'Content-Type': 'application/json',
                },
            });
            const result = await res.json();
            if (res.ok) {
                const template = result.template;
                localStorage.removeItem(`lpcd_draft_${id}`);
                set({
                    editingTemplate: {
                        id: template.id,
                        name: template.name,
                        type: template.type,
                        jsonData: template.jsonData,
                    },
                    isDirty: false,
                    history: [JSON.stringify(template.jsonData)],
                    historyIndex: 0,
                    hasDraft: false,
                    draftOriginal: null,
                });
                get().addNotice('Template reset to default!', 'success');
            } else {
                throw new Error(result.message || 'Failed to reset.');
            }
        } catch (err) {
            get().addNotice(err.message || 'Failed to reset template.', 'error');
        }
    },

    // Create blank template.
    createBlankTemplate: async () => {
        const templates = get().templates;
        const customCount = templates.filter((t) => t.type === 'custom').length;
        if (customCount >= window.lpcdEditor.maxTemplates) {
            get().addNotice(`Maximum ${window.lpcdEditor.maxTemplates} custom templates reached.`, 'error');
            return;
        }

        try {
            const blank = createBlankTemplate();
            const res = await fetch(`${window.lpcdEditor.restUrl}templates`, {
                method: 'POST',
                headers: {
                    'X-WP-Nonce': window.lpcdEditor.nonce,
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({ name: 'Untitled Template', jsonData: blank }),
            });

            const result = await res.json();
            if (!res.ok) {
                throw new Error(result.message || 'Failed to create.');
            }

            await get().fetchTemplates();
            get().enterEditor(result.id);
        } catch (err) {
            get().addNotice(err.message || 'Failed to create template.', 'error');
        }
    },

    // Delete a template.
    deleteTemplate: async (id) => {
        try {
            const res = await fetch(`${window.lpcdEditor.restUrl}templates/${id}`, {
                method: 'DELETE',
                headers: { 'X-WP-Nonce': window.lpcdEditor.nonce },
            });
            if (res.ok) {
                get().addNotice('Template deleted.', 'success');
                get().fetchTemplates();
            }
        } catch {
            get().addNotice('Failed to delete template.', 'error');
        }
    },
}));

function getDefaultBlockSettings(type) {
    switch (type) {
        case 'loginForm':
            return { ...defaultLoginFormBlock.settings };
        case 'logo':
            return { source: 'site', imageUrl: '', width: 80, alignment: 'center', linkUrl: '', marginBottom: 20 };
        case 'heading':
            return { text: 'Welcome Back', tag: 'h1', fontFamily: 'inherit', fontSize: 24, fontWeight: '700', textColor: '#1d2327', alignment: 'center', letterSpacing: 0, marginTop: 0, marginBottom: 12 };
        case 'text':
            return { text: 'Please sign in to continue.', fontFamily: 'inherit', fontSize: 14, fontWeight: '400', textColor: '#50575e', alignment: 'center', lineHeight: 1.6, marginTop: 0, marginBottom: 16 };
        case 'divider':
            return { style: 'solid', color: '#e0e0e0', width: 100, thickness: 1, alignment: 'center', marginTop: 12, marginBottom: 12 };
        case 'videoBackground':
            return {
                source: 'youtube', youtubeUrl: '', videoUrl: '', videoUpload: '',
                autoplay: true, mute: true, loop: true,
                overlayEnabled: false, overlayColor: '#000000', overlayOpacity: 0.4,
                fallbackImage: '',
            };
        case 'customHtml':
            return { htmlContent: '' };
        default:
            return {};
    }
}

export default useEditorStore;
