
import React, { useState, useRef, useEffect } from 'react';
import { IPublicClientApplication } from '@azure/msal-browser';
import type { DropdownOptions } from '../App';
import { analyzeWIPProof, getWIPChatResponse } from '../services/geminiService';
import type { AgentName } from '../types';
import { UserIcon } from './icons/UserIcon';
import { LeadAgentIcon } from './icons/LeadAgentIcon';
import { PaperClipIcon } from './icons/PaperClipIcon';
import { SendIcon } from './icons/SendIcon';
import { ChevronDownIcon } from './icons/ChevronDownIcon';
import { SpinnerIcon } from './icons/SpinnerIcon';
import { DocumentIcon } from './icons/DocumentIcon';


// --- TYPE DEFINITIONS ---
interface TextContent { type: 'text'; text: string; }
interface FilePreviewContent { type: 'file_preview'; fileName: string; previewUrl: string; mimeType: string; }
interface ConfirmationContent { type: 'confirmation'; file: File; }
interface LoadingContent { type: 'loading'; }
interface ErrorContent { type: 'error'; text: string; }

type MessageContent = TextContent | FilePreviewContent | ConfirmationContent | LoadingContent | ErrorContent;

interface Message {
  id: string;
  sender: 'user' | 'agent';
  content: MessageContent;
}

const fileToDataUrl = (file: File): Promise<string> => {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onloadend = () => resolve(reader.result as string);
    reader.onerror = reject;
    reader.readAsDataURL(file);
  });
};

// --- SUB-COMPONENTS ---

const ConfirmationComponent: React.FC<{
    dropdownOptions: DropdownOptions;
    onConfirm: (details: { channel: string; subChannel: string; proofType: string }) => void;
}> = ({ dropdownOptions, onConfirm }) => {
    const [channel, setChannel] = useState('');
    const [subChannel, setSubChannel] = useState('');
    const [proofType, setProofType] = useState('');

    const availableChannels = Object.keys(dropdownOptions.channels);
    const availableSubChannels = channel ? Object.keys(dropdownOptions.channels[channel] || {}) : [];
    const availableProofTypes = (channel && subChannel) ? (dropdownOptions.channels[channel][subChannel] || []) : [];
    const showProofType = availableProofTypes.length > 0;

    useEffect(() => {
        setSubChannel('');
        setProofType('');
    }, [channel]);

    useEffect(() => {
        if (!showProofType) setProofType('');
        else setProofType('');
    }, [subChannel, showProofType]);

    const handleSubmit = () => {
        if (channel && subChannel && (!showProofType || proofType)) {
            onConfirm({ channel, subChannel, proofType });
        }
    };

    const isSubmitDisabled = !channel || !subChannel || (showProofType && !proofType);

    return (
        <div className="p-4 bg-white rounded-lg border border-gray-200 shadow-sm space-y-3">
            <p className="font-semibold text-gray-800">Please confirm the details for this proof:</p>
            <div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
                <div className="relative">
                    <select 
                        value={channel} 
                        onChange={e => setChannel(e.target.value)} 
                        className="w-full bg-white border border-gray-300 rounded-md py-2 px-3 text-gray-900 focus:outline-none focus:ring-2 focus:ring-active-blue appearance-none"
                    >
                        <option value="" disabled>Select Channel</option>
                        {availableChannels.map(opt => <option key={opt} value={opt}>{opt}</option>)}
                    </select>
                    <ChevronDownIcon className="absolute right-3 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-500 pointer-events-none"/>
                </div>
                
                <div className="relative">
                    <select 
                        value={subChannel} 
                        onChange={e => setSubChannel(e.target.value)} 
                        disabled={!channel}
                        className="w-full bg-white border border-gray-300 rounded-md py-2 px-3 text-gray-900 focus:outline-none focus:ring-2 focus:ring-active-blue appearance-none disabled:bg-gray-100"
                    >
                        <option value="" disabled>Select Sub-Channel</option>
                        {availableSubChannels.map(opt => <option key={opt} value={opt}>{opt}</option>)}
                    </select>
                    <ChevronDownIcon className="absolute right-3 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-500 pointer-events-none"/>
                </div>
            </div>
            {showProofType && (
                 <div className="relative">
                     <select 
                        value={proofType} 
                        onChange={e => setProofType(e.target.value)} 
                        className="w-full bg-white border border-gray-300 rounded-md py-2 px-3 text-gray-900 focus:outline-none focus:ring-2 focus:ring-active-blue appearance-none"
                    >
                        <option value="" disabled>Select Proof Type</option>
                        {availableProofTypes.map(opt => <option key={opt} value={opt}>{opt}</option>)}
                    </select>
                    <ChevronDownIcon className="absolute right-3 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-500 pointer-events-none"/>
                </div>
            )}
            <button
                onClick={handleSubmit}
                disabled={isSubmitDisabled}
                className="w-full bg-active-blue text-white font-bold py-2 px-4 rounded-md hover:bg-primary-blue transition-colors disabled:bg-gray-400 disabled:cursor-not-allowed"
            >
                Confirm &amp; Analyse
            </button>
        </div>
    );
};


const MessageBubble: React.FC<{ sender: 'user' | 'agent'; children: React.ReactNode }> = ({ sender, children }) => {
    const isUser = sender === 'user';
    const bubbleClasses = isUser
        ? 'bg-active-blue text-white'
        : 'bg-white text-gray-800 border border-gray-200';
    const alignmentClasses = isUser ? 'items-end' : 'items-start';
    const avatar = isUser
        ? <div className="w-8 h-8 rounded-full bg-primary-blue flex items-center justify-center ring-2 ring-white"><UserIcon className="h-5 w-5 text-white"/></div>
        : <div className="w-8 h-8 rounded-full bg-cyan-brand flex items-center justify-center ring-2 ring-white"><LeadAgentIcon className="h-5 w-5 text-primary-blue"/></div>;
    
    const isConfirmation = React.isValidElement(children) && children.type === ConfirmationComponent;

    return (
        <div className={`flex flex-col ${alignmentClasses} w-full max-w-lg mx-auto`}>
            <div className={`flex gap-3 items-end ${isUser ? 'flex-row-reverse' : 'flex-row'}`}>
                <div className="flex-shrink-0">{avatar}</div>
                <div className={
                    isConfirmation
                        ? "w-full max-w-md"
                        : `p-3 rounded-lg max-w-xs sm:max-w-md ${bubbleClasses}`
                }>
                    {children}
                </div>
            </div>
        </div>
    );
};

// --- MAIN COMPONENT ---

interface WIPReviewerProps {
    dropdownOptions: DropdownOptions;
    msalInstance: IPublicClientApplication;
}

export const WIPReviewer: React.FC<WIPReviewerProps> = ({ dropdownOptions, msalInstance }) => {
    const [messages, setMessages] = useState<Message[]>([
        {
            id: `msg_${Date.now()}`,
            sender: 'agent',
            content: { type: 'text', text: "Hello! I'm the Lead Agent. Upload a work-in-progress file for review, or ask me a question about marketing best practices." },
        }
    ]);
    const [userInput, setUserInput] = useState('');
    const [isLoading, setIsLoading] = useState(false);
    const fileInputRef = useRef<HTMLInputElement>(null);
    const messagesEndRef = useRef<HTMLDivElement>(null);

    useEffect(() => {
        messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
    }, [messages]);

    const addMessage = (sender: 'user' | 'agent', content: MessageContent) => {
        setMessages(prev => [...prev, { id: `msg_${Date.now()}`, sender, content }]);
    };
    
    const updateLastMessage = (newContent: MessageContent) => {
        setMessages(prev => {
            const newMessages = [...prev];
            newMessages[newMessages.length - 1].content = newContent;
            return newMessages;
        });
    };

    const handleFileSelect = async (event: React.ChangeEvent<HTMLInputElement>) => {
        const file = event.target.files?.[0];
        if (!file) return;

        try {
            const previewUrl = await fileToDataUrl(file);
            addMessage('user', { type: 'file_preview', fileName: file.name, previewUrl, mimeType: file.type });
            addMessage('agent', { type: 'confirmation', file });
        } catch (error) {
            console.error("Error creating file preview:", error);
            addMessage('agent', { type: 'error', text: "Sorry, I couldn't load a preview for that file. Please try another file." });
        }

        // Reset file input
        if (event.target) event.target.value = '';
    };

    const handleSendMessage = async (e: React.FormEvent) => {
        e.preventDefault();
        const trimmedInput = userInput.trim();
        if (!trimmedInput || isLoading) return;

        addMessage('user', { type: 'text', text: trimmedInput });
        setUserInput('');
        setIsLoading(true);
        addMessage('agent', { type: 'loading' });

        try {
            const responseText = await getWIPChatResponse(trimmedInput);
            updateLastMessage({ type: 'text', text: responseText });
        } catch (err) {
            console.error("Chat response failed:", err);
            updateLastMessage({ type: 'error', text: "Sorry, I couldn't get a response. Please try again." });
        } finally {
            setIsLoading(false);
        }
    };

    const handleConfirmAnalysis = async (
        messageId: string,
        details: { channel: string; subChannel: string; proofType: string },
        file: File
    ) => {
        setIsLoading(true);
        // Replace confirmation message with loading indicator
        setMessages(prev => prev.map(msg => msg.id === messageId ? { ...msg, content: { type: 'loading' } } : msg));

        try {
            const summary = await analyzeWIPProof(file, () => {}, msalInstance);
            setMessages(prev => prev.map(msg => msg.id === messageId ? { ...msg, content: { type: 'text', text: summary } } : msg));
        } catch (err) {
            console.error("Analysis failed:", err);
            setMessages(prev => prev.map(msg => msg.id === messageId ? { ...msg, content: { type: 'error', text: "Sorry, an error occurred during the analysis. Please try again." } } : msg));
        } finally {
            setIsLoading(false);
        }
    };
    
    return (
        <div className="flex flex-col h-full bg-grey-100">
            <header className="p-4 border-b border-gray-200 bg-white/80 backdrop-blur-sm flex-shrink-0">
                <h1 className="text-xl font-bold text-primary-blue text-center">WIP Reviewer</h1>
            </header>

            {/* Message Display Area */}
            <div className="flex-1 overflow-y-auto p-4 space-y-6">
                {messages.map((msg) => (
                    <MessageBubble key={msg.id} sender={msg.sender}>
                        {(() => {
                            switch (msg.content.type) {
                                case 'text':
                                    return <p className="whitespace-pre-wrap">{msg.content.text}</p>;
                                case 'file_preview':
                                    const { mimeType, previewUrl, fileName } = msg.content;
                                    if (mimeType.startsWith('image/')) {
                                        return <img src={previewUrl} alt={fileName} className="max-w-full h-auto rounded-md object-contain" />;
                                    }
                                    return (
                                        <div className="flex items-center gap-3 p-2 bg-black/20 rounded-md">
                                            <DocumentIcon className="h-8 w-8 text-white"/>
                                            <span className="font-semibold truncate">{fileName}</span>
                                        </div>
                                    );
                                case 'confirmation':
                                    return <ConfirmationComponent
                                                dropdownOptions={dropdownOptions}
                                                onConfirm={(details) => handleConfirmAnalysis(msg.id, details, msg.content.file)}
                                            />;
                                case 'loading':
                                    return (
                                        <div className="flex items-center gap-2 text-gray-600">
                                            <SpinnerIcon className="h-5 w-5 custom-spinner"/>
                                            <span>Thinking...</span>
                                        </div>
                                    );
                                case 'error':
                                    return <p className="text-red-600 font-medium">{msg.content.text}</p>
                                default:
                                    return null;
                            }
                        })()}
                    </MessageBubble>
                ))}
                <div ref={messagesEndRef} />
            </div>

            {/* Message Input Area */}
            <div className="flex-shrink-0 p-4 bg-white/80 backdrop-blur-sm border-t border-gray-200">
                <div className="max-w-lg mx-auto">
                    <form onSubmit={handleSendMessage} className="relative flex items-center">
                        <input type="file" ref={fileInputRef} onChange={handleFileSelect} className="hidden" />
                        <button
                            type="button"
                            onClick={() => fileInputRef.current?.click()}
                            disabled={isLoading}
                            className="p-2 text-gray-500 hover:text-active-blue rounded-full transition-colors disabled:opacity-50"
                            aria-label="Attach file"
                        >
                            <PaperClipIcon className="h-6 w-6"/>
                        </button>
                        <textarea
                            value={userInput}
                            onChange={(e) => setUserInput(e.target.value)}
                            onKeyDown={(e) => {
                                if (e.key === 'Enter' && !e.shiftKey) {
                                    e.preventDefault();
                                    handleSendMessage(e);
                                }
                            }}
                            className="w-full p-2.5 mx-2 border border-gray-300 rounded-lg resize-none focus:ring-2 focus:ring-active-blue focus:border-active-blue transition"
                            placeholder="Type your message..."
                            rows={1}
                            disabled={isLoading}
                        />
                        <button
                            type="submit"
                            className="p-2.5 rounded-full text-white bg-active-blue hover:bg-primary-blue disabled:bg-gray-400 transition-colors"
                            disabled={!userInput.trim() || isLoading}
                            aria-label="Send message"
                        >
                            <SendIcon className="h-5 w-5" />
                        </button>
                    </form>
                </div>
            </div>
        </div>
    );
};
