import type { Component } from 'solid-js';
import { createSignal, createMemo, onMount, Show } from 'solid-js';
import { FileText, ChevronDown, CheckCircle2, X } from 'lucide-solid';
import { Portal } from 'solid-js/web';

import { appStore } from '../store/appStore';
import type { Scope, SubScope, EstimateItem } from '../types';
import type { ExtractedItem } from '../utils/csv-parser';
import { GENERAL_NOTES_DEFAULT, GENERAL_PRE_NOTES_DEFAULT } from '../company-info';

import PrintEstimate from './PrintEstimate';
import NoteEditor from './NoteEditor';
import CalculatorPopover from './CalculatorPopover';
import CloudLoadModal from './CloudLoadModal';
import ExportTableModal from './ExportTableModal';
import ApplyTemplateModal from './ApplyTemplateModal';
import HistoryModal from './estimate-builder/HistoryModal';
import { NewEstimateModal } from './estimate-builder/NewEstimateModal';

// Import extracted components & hooks
import { useEstimateCalculations } from './estimate-builder/useEstimateCalculations';
import { useSelectionManager } from './estimate-builder/useSelectionManager';
import { useDragAndDrop } from './estimate-builder/useDragAndDrop';
import { useEstimateSync } from './estimate-builder/useEstimateSync';

import { BuilderHeader } from './estimate-builder/BuilderHeader';
import { BuilderSidebar } from './estimate-builder/BuilderSidebar';
import { ProjectDetailsForm } from './estimate-builder/ProjectDetailsForm';
import { UnassignedItemsSection } from './estimate-builder/UnassignedItemsSection';
import { ExecutiveSummary } from './estimate-builder/ExecutiveSummary';
import { SelectionToolbar } from './estimate-builder/SelectionToolbar';
import { ValidationStatusBar } from './estimate-builder/ValidationStatusBar';
import { ScopesList } from './estimate-builder/ScopesList';

interface EstimateBuilderProps {
    initialItems: ExtractedItem[];
}

const EstimateBuilder: Component<EstimateBuilderProps> = (props) => {
    // 1. Initialize State
    const { scopes, setScopes, subScopes, setSubScopes, estimateItems: items, setEstimateItems: setItems, clientInfo, jobInfo, generalEstimateNotes, setGeneralEstimateNotes, generalPreNotes, setGeneralPreNotes } = appStore;

    const [isSidebarCollapsed, setIsSidebarCollapsed] = createSignal(false);
    const [isNotesExpanded, setIsNotesExpanded] = createSignal(true);
    const [isPreNotesExpanded, setIsPreNotesExpanded] = createSignal(true);
    
    // Cloud Modals
    const [showSaveModal, setShowSaveModal] = createSignal(false);
    const [showLoadModal, setShowLoadModal] = createSignal(false);
    const [showHistoryModal, setShowHistoryModal] = createSignal(false);
    const [showNewEstimateModal, setShowNewEstimateModal] = createSignal(false);
    const [showExportTableModal, setShowExportTableModal] = createSignal(false);
    const [applyTemplateScopeId, setApplyTemplateScopeId] = createSignal<string | null>(null);

    // 2. Initialize custom hooks/primitives
    const { selectedIds, setSelectedIds, lastSelectedId, setLastSelectedId, toggleSelection, clearSelection, copyColumnSum } = useSelectionManager();
    const { grandTotals, validationStats, selectionTotals } = useEstimateCalculations(selectedIds);
    
    const updateItem = (id: string, updates: Partial<EstimateItem>) => {
        setItems(item => item.id === id, updates);
    };
    
    const { hoveredScopeId, setHoveredScopeId, handleDragStart, handleDrop } = useDragAndDrop(selectedIds, setSelectedIds, updateItem);
    const { exportEstimate, importEstimate, saveToCloud, saveChangesToCloud, saveAsNewestToCloud, checkoutVersion, isCloudLoading } = useEstimateSync(setShowSaveModal);

    onMount(() => {
        if (!generalEstimateNotes()) setGeneralEstimateNotes(GENERAL_NOTES_DEFAULT);
        if (!generalPreNotes()) setGeneralPreNotes(GENERAL_PRE_NOTES_DEFAULT);

        if (items.length === 0 && props.initialItems.length > 0) {
            const transformed: EstimateItem[] = props.initialItems.map(item => ({
                id: item.id,
                description: item.description,
                quantity: parseFloat(item.quantity.replace(/,/g, '')) || 0,
                unitPrice: 0,
                markup: 0,
                markupType: 'percent',
                contingency: 0,
                contingencyType: 'percent'
            }));
            setItems(transformed);
        }
    });

    const unassignedItems = createMemo(() => items.filter(i => !i.scopeId));
    const anyDescriptionIsLong = createMemo(() => items.some(item => (item.description || '').length > 120));

    const finalizeBid = () => {
        window.print();
    };

    const addScope = () => {
        const scopeId = crypto.randomUUID();
        const newScope: Scope = {
            id: scopeId,
            name: 'New Scope',
            managementFee: 0,
            managementFeeType: 'percent',
            managementFeeQuantity: 1,
            managementFeeRate: 0,
            deliveryFee: 0,
            deliveryFeeType: 'percent',
            deliveryFeeQuantity: 1,
            deliveryFeeRate: 0,
            useManagementLogic: 'percent',
            useDeliveryLogic: 'percent',
            estimatorNotes: '',
            bidDescription: '**Material and labor to install #**\n**Includes:**\n- #\n**Does Not Include:**\n- #'
        };
        setScopes(prev => [...prev, newScope]);
        addSubScopeWithName(scopeId, 'Materials');
        addSubScopeWithName(scopeId, 'Labor');
        return scopeId;
    };

    const addSubScopeWithName = (scopeId: string, name: string) => {
        const newSubScope: SubScope = {
            id: crypto.randomUUID(),
            name,
            scopeId
        };
        setSubScopes(prev => [...prev, newSubScope]);
        return newSubScope.id;
    };

    const addSubScope = (scopeId: string) => {
        addSubScopeWithName(scopeId, 'New Sub-scope');
    };

    const deleteItem = (id: string) => {
        setItems(items.filter(i => i.id !== id));
        setSelectedIds(prev => prev.filter(selId => selId !== id));
        if (lastSelectedId() === id) setLastSelectedId(null);
    };

    const duplicateItem = (id: string) => {
        const itemIndex = items.findIndex(i => i.id === id);
        if (itemIndex !== -1) {
            const itemToClone = items[itemIndex];
            const newItem: EstimateItem = { ...itemToClone, id: crypto.randomUUID() };
            const newItems = [...items];
            newItems.splice(itemIndex + 1, 0, newItem);
            setItems(newItems);
        }
    };

    const copySubScopeItems = (sourceSubScopeId: string, targetSubScopeId: string) => {
        const targetSubScope = subScopes.find(ss => ss.id === targetSubScopeId);
        if (!targetSubScope) return;
        const itemsToClone = items.filter(i => i.subScopeId === sourceSubScopeId);
        const newClonedItems = itemsToClone.map(item => ({
            ...item, id: crypto.randomUUID(), subScopeId: targetSubScopeId, scopeId: targetSubScope.scopeId
        }));
        setItems(prev => [...prev, ...newClonedItems]);
    };

    const updateScope = (id: string, updates: Partial<Scope>) => {
        setScopes(s => s.id === id, updates);
    };

    const updateSubScope = (id: string, updates: Partial<SubScope>) => {
        setSubScopes(ss => ss.id === id, updates);
    };

    const deleteScope = (id: string) => {
        setScopes(scopes.filter(s => s.id !== id));
        setItems(i => i.scopeId === id, { scopeId: undefined, subScopeId: undefined });
        setSubScopes(subScopes.filter(ss => ss.scopeId !== id));
    };

    const deleteSubScope = (id: string) => {
        setSubScopes(subScopes.filter(ss => ss.id !== id));
        setItems(i => i.subScopeId === id, { subScopeId: undefined });
    };

    const handleBulkUpdate = (scopeId: string, subScopeId: string | undefined, updates: any) => {
        setItems(item => item.scopeId === scopeId && (subScopeId === undefined || item.subScopeId === subScopeId), updates);
    };

    const formatNumber = (num: number) => {
        return num.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 });
    };

    const [copyToast, setCopyToast] = createSignal<string | null>(null);

    return (
        <div class="w-full flex flex-col min-h-screen bg-white shadow-2xl relative print:shadow-none print:border-none print:rounded-none">
            <PrintEstimate
                scopes={scopes}
                subScopes={subScopes}
                items={items}
                grandTotals={grandTotals}
                clientInfo={clientInfo}
                jobInfo={jobInfo}
                generalEstimateNotes={generalEstimateNotes()}
                generalPreNotes={generalPreNotes()}
                formatNumber={formatNumber}
                hideColumns={anyDescriptionIsLong()}
            />

            <div class="no-print flex flex-col min-h-dvh">
                <BuilderHeader 
                    isSidebarCollapsed={isSidebarCollapsed()} 
                    onToggleSidebar={() => setIsSidebarCollapsed(!isSidebarCollapsed())}
                    onAddScope={addScope}
                    onShowNewEstimateModal={() => setShowNewEstimateModal(true)}
                    onImportEstimate={importEstimate}
                    onShowExportTableModal={() => setShowExportTableModal(true)}
                    onExportEstimate={exportEstimate}
                    onShowLoadModal={() => setShowLoadModal(true)}
                    onShowSaveModal={() => setShowSaveModal(true)}
                    onShowHistoryModal={() => setShowHistoryModal(true)}
                    onSaveChanges={() => appStore.isLatestVersion() ? saveChangesToCloud() : saveAsNewestToCloud()}
                />

                <div
                    style={{
                        display: 'grid',
                        'grid-template-columns': isSidebarCollapsed() ? '0px 1fr' : '18rem 1fr',
                        transition: 'grid-template-columns 500ms ease',
                        'align-items': 'start',
                        flex: '1',
                    }}
                >
                    <BuilderSidebar
                        isCollapsed={isSidebarCollapsed()}
                        onToggleSidebar={() => setIsSidebarCollapsed(!isSidebarCollapsed())}
                        unassignedItems={unassignedItems()}
                        grandTotals={grandTotals()}
                        hoveredScopeId={hoveredScopeId()}
                        setHoveredScopeId={setHoveredScopeId}
                        onDrop={handleDrop}
                        onAddScope={addScope}
                    />

                    <main onClick={clearSelection} class="min-w-0 p-4 md:p-8 bg-zinc-50/50 space-y-8 min-h-screen">
                        <ProjectDetailsForm />

                        <div class="bg-muted/30 border border-border rounded-3xl p-6 mb-8">
                            <div class="flex items-center justify-between mb-4">
                                <div class="flex items-center gap-3 text-foreground">
                                    <div class="p-2 bg-background rounded-xl shadow-sm">
                                        <FileText class="w-5 h-5 text-primary" />
                                    </div>
                                    <div>
                                        <h3 class="font-black text-lg">General Pre-Notes</h3>
                                        <p class="text-muted-foreground text-[10px] font-bold uppercase tracking-wider">Project-wide preamble & terms</p>
                                    </div>
                                </div>
                                <button
                                    onClick={() => setIsPreNotesExpanded(!isPreNotesExpanded())}
                                    class="p-2 hover:bg-background rounded-xl transition-all text-muted-foreground"
                                >
                                    <ChevronDown class={`w-5 h-5 transition-transform ${isPreNotesExpanded() ? 'rotate-180' : ''}`} />
                                </button>
                            </div>

                            <Show when={isPreNotesExpanded()}>
                                <div class="p-6 pt-0">
                                    <NoteEditor
                                        label="Pre-Scope Terms"
                                        value={generalPreNotes()}
                                        onUpdate={setGeneralPreNotes}
                                        icon={FileText}
                                        highlight={generalPreNotes().includes('#')}
                                    />
                                </div>
                            </Show>
                        </div>

                        <UnassignedItemsSection 
                            unassignedItems={unassignedItems()}
                            isSidebarCollapsed={isSidebarCollapsed}
                            anyDescriptionIsLong={anyDescriptionIsLong}
                            selectedIds={selectedIds()}
                            onDrop={handleDrop}
                            clearSelection={clearSelection}
                            updateItem={updateItem}
                            deleteItem={deleteItem}
                            handleDragStart={handleDragStart}
                            duplicateItem={duplicateItem}
                            toggleSelection={toggleSelection}
                        />

                        <ScopesList 
                            scopes={scopes}
                            subScopes={subScopes}
                            items={items}
                            isNotesExpanded={isNotesExpanded()}
                            setIsNotesExpanded={setIsNotesExpanded}
                            generalEstimateNotes={generalEstimateNotes()}
                            setGeneralEstimateNotes={setGeneralEstimateNotes}
                            updateScope={updateScope}
                            deleteScope={deleteScope}
                            updateItem={updateItem}
                            deleteItem={deleteItem}
                            addSubScope={addSubScope}
                            updateSubScope={updateSubScope}
                            deleteSubScope={deleteSubScope}
                            handleDragStart={handleDragStart}
                            handleDrop={handleDrop}
                            handleBulkUpdate={handleBulkUpdate}
                            duplicateItem={duplicateItem}
                            copySubScopeItems={copySubScopeItems}
                            setApplyTemplateScopeId={setApplyTemplateScopeId}
                            isSidebarCollapsed={isSidebarCollapsed}
                            selectedIds={selectedIds()}
                            toggleSelection={toggleSelection}
                            clearSelection={clearSelection}
                            anyDescriptionIsLong={anyDescriptionIsLong}
                            addScope={addScope}
                        />

                        <ValidationStatusBar validationStats={validationStats()} />

                        <ExecutiveSummary totals={grandTotals()} onFinalizeBid={finalizeBid} />
                    </main>
                </div>
                
                <CalculatorPopover />
            </div>

            <SelectionToolbar 
                selectedIds={selectedIds()}
                selectionTotals={selectionTotals()}
                onClearSelection={() => { setSelectedIds([]); setLastSelectedId(null); }}
                onCopyColumnSum={(col) => copyColumnSum(col, selectionTotals()[col], setCopyToast)}
            />

            <Show when={copyToast()}>
                <div class="fixed bottom-6 right-6 bg-gray-900 border border-gray-800 text-white px-4 py-3 rounded-xl shadow-2xl flex items-center gap-3 animate-in slide-in-from-bottom-5 z-50 pointer-events-none fade-out-90 duration-300">
                    <CheckCircle2 class="w-5 h-5 text-green-400" />
                    <span class="font-medium text-sm drop-shadow-sm">{copyToast()}</span>
                </div>
            </Show>

            <Show when={showSaveModal()}>
                <Portal>
                    <div class="fixed inset-0 z-[100] flex items-center justify-center bg-background/80 backdrop-blur-sm p-4 animate-in fade-in duration-200">
                        <div class="bg-card w-full max-w-md rounded-3xl shadow-premium border border-border p-6 animate-in zoom-in-95 duration-200">
                            <div class="flex items-center justify-between mb-6">
                                <h3 class="text-xl font-black">Save to Cloud</h3>
                                <button onClick={() => setShowSaveModal(false)} class="p-2 hover:bg-muted rounded-xl transition-colors">
                                    <X class="w-5 h-5 text-muted-foreground" />
                                </button>
                            </div>
                            <div class="space-y-4">
                                <input
                                    type="text"
                                    id="cloud-save-name"
                                    placeholder="Estimate Name (e.g. Smith Master Bath)"
                                    class="w-full bg-muted/30 border border-border/60 rounded-xl px-4 py-3 text-sm focus:bg-background focus:ring-2 focus:ring-primary/20 focus:border-primary outline-none transition-all font-medium"
                                    value={appStore.estimateName()}
                                />
                                <div class="flex gap-3 justify-end mt-6">
                                    <button onClick={() => setShowSaveModal(false)} class="px-5 py-2.5 rounded-xl font-bold text-sm hover:bg-muted transition-colors">Cancel</button>
                                    <button
                                        disabled={isCloudLoading()}
                                        onClick={() => {
                                            const name = (document.getElementById('cloud-save-name') as HTMLInputElement).value;
                                            if (name) saveToCloud(name);
                                        }}
                                        class="px-5 py-2.5 bg-primary text-primary-foreground rounded-xl font-bold text-sm shadow-premium hover:shadow-premium-hover transition-all disabled:opacity-50"
                                    >
                                        {isCloudLoading() ? 'Saving...' : 'Save Estimate'}
                                    </button>
                                </div>
                            </div>
                        </div>
                    </div>
                </Portal>
            </Show>

            <CloudLoadModal show={showLoadModal()} onClose={() => setShowLoadModal(false)} />
            <ExportTableModal show={showExportTableModal()} onClose={() => setShowExportTableModal(false)} />
            <ApplyTemplateModal show={!!applyTemplateScopeId()} scopeId={applyTemplateScopeId()} onClose={() => setApplyTemplateScopeId(null)} />
            <HistoryModal show={showHistoryModal()} onClose={() => setShowHistoryModal(false)} onCheckout={checkoutVersion} />
            
            <NewEstimateModal 
                show={showNewEstimateModal()} 
                onClose={() => setShowNewEstimateModal(false)}
                onResetCSV={() => {
                    appStore.resetEstimate();
                    setShowNewEstimateModal(false);
                }}
                onManualEstimate={() => {
                    appStore.resetEstimate();
                    setItems([{
                        id: crypto.randomUUID(),
                        description: 'Item',
                        quantity: 1,
                        unitPrice: 0,
                        markup: 0,
                        markupType: 'percent',
                        contingency: 0,
                        contingencyType: 'percent'
                    }]);
                    setShowNewEstimateModal(false);
                }}
            />
        </div>
    );
};

export default EstimateBuilder;
