import { create } from 'zustand';
import { ChatService } from '../../services/chat-service';
import { LLMService } from '../../services/llm-service';
import { DraftService } from '../db/draft-service';
import type { ChatMessage } from '../db';
import type { Intent } from '../llm/intent-detector';

/**
 * Draft interface for the store
 */
export interface Draft {
    id: number;
    sessionId: string;
    title: string;
    content: string;  // Markdown formatted
    tags: string[];
    createdAt: number;
    status: 'draft' | 'completed' | 'regenerated';
}

interface ChatState {
    messages: ChatMessage[];
    isLoading: boolean;
    isTyping: boolean;
    currentIntent: Intent | null;
    isProcessing: boolean;
    isFastTrack: boolean;
    // Draft state
    currentDraft: Draft | null;
    isDrafting: boolean;
    // Draft view state
    showDraftView: boolean;
    // Refinement state (Story 2.3)
    isRefining: boolean;
    refinementDraftId: number | null;
    originalDraft: Draft | null;
    // Actions
    toggleFastTrack: () => void;
    addMessage: (content: string, role: 'user' | 'assistant') => Promise<void>;
    generateDraft: (sessionId?: string) => Promise<void>;
    clearDraft: () => void;
    hydrate: (sessionId?: string) => Promise<void>;
    // Draft view actions
    closeDraftView: () => void;
    approveDraft: (draftId: number) => Promise<void>;
    rejectDraft: (draftId: number) => void;
    // Refinement actions (Story 2.3)
    startRefinement: (draftId: number) => Promise<void>;
    submitRefinementFeedback: (feedback: string) => Promise<void>;
    cancelRefinement: () => void;
    // Completion actions (Story 2.4)
    completeDraft: (draftId: number) => Promise<void>;
    copyDraftToClipboard: (draftId: number) => Promise<void>;
    // Deletion actions (Story 3.2)
    deleteDraft: (draftId: number) => Promise<boolean>;
}

export const useChatStore = create<ChatState>((set, get) => ({
    messages: [],
    isLoading: true,
    isTyping: false,
    currentIntent: null,
    isProcessing: false,
    isFastTrack: false,
    currentDraft: null,
    isDrafting: false,
    showDraftView: false,
    // Refinement state initialization (Story 2.3)
    isRefining: false,
    refinementDraftId: null,
    originalDraft: null,

    toggleFastTrack: () => set((state) => ({ isFastTrack: !state.isFastTrack })),

    generateDraft: async (sessionId) => {
        const sid = sessionId || Date.now().toString();
        set({ isDrafting: true });

        // Use new service method for cleaner architecture
        await ChatService.generateGhostwriterDraftStream(
            get().messages,
            get().currentIntent || undefined,
            sid,
            {
                onToken: (token) => {
                    // Update content incrementally for UI feedback
                    set(state => {
                        const currentContent = state.currentDraft?.content || '';
                        const updatedContent = currentContent + token;

                        // Parse title on the fly if needed (simple heuristic)
                        let title = state.currentDraft?.title || 'Untitled Draft';
                        const titleMatch = token.match(/^#\s+(.+)$/m);
                        if (titleMatch) title = titleMatch[1];

                        return {
                            currentDraft: {
                                id: 0,
                                sessionId: sid,
                                title,
                                content: updatedContent,
                                tags: [],
                                createdAt: Date.now(),
                                status: 'draft' as const
                            }
                        };
                    });
                },
                onComplete: (draft) => {
                    set({ currentDraft: draft, isDrafting: false, showDraftView: true });
                },
                onError: (error) => {
                    set({
                        currentDraft: {
                            id: 0,
                            sessionId: sid,
                            title: 'Draft Failed',
                            content: `# Draft Generation Failed\n\n${error}`,
                            tags: [],
                            createdAt: Date.now(),
                            status: 'draft' as const
                        },
                        isDrafting: false
                    });
                }
            }
        );
    },

    clearDraft: () => set({ currentDraft: null, showDraftView: false }),

    // Draft view actions
    closeDraftView: () => set({ showDraftView: false }),

    approveDraft: async (draftId: number) => {
        // Alias for completeDraft
        await get().completeDraft(draftId);
    },

    rejectDraft: (draftId: number) => {
        // Just close the view and return to chat
        // Story 2.3 will handle the refinement flow
        set({ showDraftView: false });
    },

    // Refinement actions (Story 2.3)
    startRefinement: async (draftId: number) => {
        // Architecture Compliance: Logic moved to Service Layer
        const draft = await ChatService.startRefinement(draftId);

        // Update refinement state
        set({
            isRefining: true,
            refinementDraftId: draftId,
            originalDraft: draft,
        });
    },

    submitRefinementFeedback: async (feedback: string) => {
        const { originalDraft } = get();
        if (!originalDraft) {
            console.error("Refinement submitted without original draft");
            return;
        }

        // Architecture Compliance: Logic moved to Service Layer
        const refinedDraft = await ChatService.submitRefinementFeedback(feedback, originalDraft);

        // Exit refinement mode after regeneration and update current draft
        set({
            isRefining: false,
            refinementDraftId: null,
            originalDraft: null,
            currentDraft: refinedDraft, // Update the draft view with the new version
            showDraftView: true // Ensure the view is open
        });
    },

    cancelRefinement: () => {
        // Clear refinement state
        set({
            isRefining: false,
            refinementDraftId: null,
            originalDraft: null,
        });
    },

    // Story 2.4: Completion actions
    completeDraft: async (draftId: number) => {
        // Architecture Compliance: Logic moved to Service Layer
        // ChatService.approveDraft handles copy + marking as completed
        await ChatService.approveDraft(draftId);

        // Clear from store (closes DraftViewSheet)
        set({ currentDraft: null, showDraftView: false });
    },

    copyDraftToClipboard: async (draftId: number) => {
        // Copy without closing sheet
        const draft = await DraftService.getDraftById(draftId);
        if (!draft) return;

        // Use clipboard utility
        const { copyToClipboard } = await import('../utils/clipboard');
        await copyToClipboard(draft.content);
        // Don't clear currentDraft - keep sheet open
    },

    // Story 3.2: Deletion action
    deleteDraft: async (draftId: number) => {
        // Architecture Compliance: Logic moved to Service Layer
        const success = await DraftService.deleteDraft(draftId);

        if (success) {
            // Check if we deleted the current draft
            const currentDraft = get().currentDraft;
            if (currentDraft && currentDraft.id === draftId) {
                set({ currentDraft: null, showDraftView: false });
            }
        }

        return success;
    },

    addMessage: async (content, role) => {
        // Fix: Intercept messages during refinement mode
        if (get().isRefining && role === 'user') {
            await get().submitRefinementFeedback(content);
            return;
        }

        // Story 3.2: Include sessionId for cascade delete
        // Use a sessionId based on current time for user messages
        const currentSessionId = 'session-' + Date.now();

        // Save user message
        const savedUserMsg = await ChatService.saveMessage({
            sessionId: currentSessionId,
            content,
            role,
            timestamp: Date.now()
        });

        set((state) => ({
            messages: [...state.messages, savedUserMsg]
        }));

        // If user sent message, get AI response
        if (role === 'user') {
            // Fast Track Bypass - Trigger Ghostwriter Directly
            if (get().isFastTrack) {
                // VIOLATION FIX: Set isDrafting instead of isTyping for Fast Track
                set({
                    isProcessing: true,
                    isDrafting: true,  // Fix: Show drafting indicator
                    currentIntent: 'insight'
                });

                const sid = Date.now().toString();

                // VIOLATION FIX: Use streaming for Fast Track too
                await ChatService.generateGhostwriterDraftStream(
                    get().messages,
                    'insight',
                    sid,
                    {
                        onToken: (token) => {
                            // Update draft state incrementally
                            set(state => {
                                const currentContent = state.currentDraft?.content || '';
                                return {
                                    currentDraft: {
                                        id: 0,
                                        sessionId: sid,
                                        title: 'Drafting...',
                                        content: currentContent + token,
                                        tags: [],
                                        createdAt: Date.now(),
                                        status: 'draft' as const
                                    }
                                };
                            });
                        },
                        onComplete: async (draft) => {
                            // Add system message indicating draft is ready
                            // Story 3.2: Include sessionId for cascade delete
                            const readyMsg = await ChatService.saveMessage({
                                sessionId: sid,
                                content: `✨ Draft ready! I've transformed your insight into a polished post.`,
                                role: 'assistant',
                                timestamp: Date.now(),
                                intent: 'insight'
                            });

                            set((state) => ({
                                currentDraft: draft,
                                isDrafting: false,
                                isProcessing: false,
                                showDraftView: true,
                                messages: [...state.messages, readyMsg]
                            }));
                        },
                        onError: async (error) => {
                            const errorMsg = await ChatService.saveMessage({
                                sessionId: sid,
                                content: error || "Failed to generate draft.",
                                role: 'assistant',
                                timestamp: Date.now()
                            });

                            set((state) => ({
                                isDrafting: false,
                                isProcessing: false,
                                messages: [...state.messages, errorMsg]
                            }));
                        }
                    }
                );
                return;
            }

            // Normal Flow - Teacher Agent
            set({ isProcessing: true, isTyping: true });

            try {
                // Initialize streaming message placeholder
                // Story 3.2: Include sessionId for consistency (placeholder only)
                const streamPlaceholder: ChatMessage = {
                    id: -Date.now(),
                    sessionId: 'session-' + Date.now(), // Placeholder session ID
                    role: 'assistant',
                    content: '',
                    timestamp: Date.now(),
                };

                set((state) => ({
                    messages: [...state.messages, streamPlaceholder]
                }));

                await LLMService.getTeacherResponseStream(
                    content,
                    get().messages.filter(m => m.id !== streamPlaceholder.id),
                    {
                        onIntent: (intent) => {
                            set({ currentIntent: intent });
                            set((state) => ({
                                messages: state.messages.map(m =>
                                    m.id === streamPlaceholder.id
                                        ? { ...m, intent }
                                        : m
                                )
                            }));
                        },
                        onToken: (token) => {
                            set({ isTyping: false });
                            set((state) => ({
                                messages: state.messages.map(m =>
                                    m.id === streamPlaceholder.id
                                        ? { ...m, content: m.content + token }
                                        : m
                                )
                            }));
                        },
                        onComplete: async (fullText) => {
                            // Story 3.2: Include sessionId for cascade delete
                            // Use a sessionId based on current time for teacher responses
                            const currentSessionId = 'session-' + Date.now();
                            const savedAiMsg = await ChatService.saveMessage({
                                sessionId: currentSessionId,
                                content: fullText,
                                role: 'assistant',
                                timestamp: Date.now(),
                                intent: get().currentIntent || undefined
                            });

                            set((state) => ({
                                messages: state.messages.map(m =>
                                    m.id === streamPlaceholder.id
                                        ? savedAiMsg
                                        : m
                                )
                            }));
                            set({ isProcessing: false });
                        },
                        onError: async (errorResponse) => {
                            const errorMessage = errorResponse.error?.message ||
                                "I'm having trouble connecting right now.";

                            // Story 3.2: Include sessionId for cascade delete
                            const currentSessionId = 'session-' + Date.now();
                            const savedErrorMsg = await ChatService.saveMessage({
                                sessionId: currentSessionId,
                                content: errorMessage,
                                role: 'assistant',
                                timestamp: Date.now()
                            });

                            set((state) => ({
                                messages: state.messages.map(m =>
                                    m.id === streamPlaceholder.id
                                        ? savedErrorMsg
                                        : m
                                )
                            }));
                            set({ isProcessing: false, isTyping: false });
                        }
                    }
                );
            } catch (error) {
                set({ isProcessing: false, isTyping: false });
                // Story 3.2: Include sessionId for cascade delete
                const currentSessionId = 'session-' + Date.now();
                const fallbackMsg = await ChatService.saveMessage({
                    sessionId: currentSessionId,
                    content: "Something went wrong. Please try again.",
                    role: 'assistant',
                    timestamp: Date.now()
                });
                set((state) => ({
                    messages: [...state.messages, fallbackMsg]
                }));
            }
        }
    },

    hydrate: async (sessionId?: string) => {
        set({ isLoading: true });
        try {
            const history = await ChatService.getHistory(sessionId);
            set({ messages: history });
        } finally {
            set({ isLoading: false });
        }
    }
}));
