import React, { createContext, useContext, useState, useCallback, useEffect, useMemo } from 'react';
import { useAdmin } from './AdminContext';
import { API_BASE_URL } from '../auth/authConfig';

// ─── Channel Configuration ──────────────────────────────────
export const CHANNELS = ['google_ads', 'meta', 'tiktok'];

export const CHANNEL_META = {
    google_ads: { color: '#4285F4', label: 'Google Ads' },
    meta:       { color: '#8B5CF6', label: 'Meta' },
    tiktok:     { color: '#FF004F', label: 'TikTok' },
};

// Default fallbacks when metadata tables haven't been seeded
const FALLBACK_ICONS = {
    restaurant: '🍽️', retail: '🛍️', b2b_services: '💼',
    local_services: '🏠', health_wellness: '🏥', general: '📋',
    automotive: '🚗', education: '🎓', legal_services: '⚖️',
    fitness: '🏋️', real_estate: '🏢', pet_services: '🐾', travel: '✈️',
};

const FALLBACK_OBJ_COLORS = {
    awareness: '#7dca7d', traffic: '#4fc3f7', leads: '#ffb74d',
    conversions: '#ce93d8', sales: '#ef5350',
};


// ─── Context ────────────────────────────────────────────────
const TemplatesContext = createContext(null);

export function useTemplates() {
    const ctx = useContext(TemplatesContext);
    if (!ctx) throw new Error('useTemplates must be used within <TemplatesProvider>');
    return ctx;
}


// ─── Provider ───────────────────────────────────────────────
export function TemplatesProvider({ children }) {
    const { data, sessionToken, apiCall, refresh } = useAdmin();
    const templates = data?.templates || [];

    // ─── Metadata state ─────────────────────────────────────
    const [categories, setCategories] = useState([]);
    const [objectives, setObjectives] = useState([]);
    const [metaLoading, setMetaLoading] = useState(true);

    // ─── Sidebar filter state ───────────────────────────────
    const [selectedCategory, setSelectedCategory] = useState(null);
    const [selectedObjective, setSelectedObjective] = useState(null);
    const [editMode, setEditMode] = useState(false);

    // ─── Form state ─────────────────────────────────────────
    const [showForm, setShowForm] = useState(false);
    const [editingId, setEditingId] = useState(null);
    const [addingToGroup, setAddingToGroup] = useState(null);

    // ─── New category state ─────────────────────────────────
    const [showNewCat, setShowNewCat] = useState(false);
    const [newCatName, setNewCatName] = useState('');
    const [newCatIcon, setNewCatIcon] = useState('');

    // ─── Fetch category & objective metadata ────────────────
    const fetchMetadata = useCallback(async () => {
        if (!sessionToken) return;
        setMetaLoading(true);
        try {
            const [catRes, objRes] = await Promise.all([
                fetch(`${API_BASE_URL}/api/admin/template-config/categories`, {
                    headers: { 'X-Session-Token': sessionToken }
                }).catch(() => null),
                fetch(`${API_BASE_URL}/api/admin/template-config/objectives`, {
                    headers: { 'X-Session-Token': sessionToken }
                }).catch(() => null),
            ]);

            const catData = catRes ? await catRes.json().catch(() => null) : null;
            const objData = objRes ? await objRes.json().catch(() => null) : null;

            if (catData?.ok && catData.categories) {
                setCategories([...catData.categories].sort((a, b) => a.name.localeCompare(b.name)));
            } else {
                const catNames = [...new Set(templates.map(t => t.businessCategory))].sort();
                setCategories(catNames.map((name, i) => ({
                    categoryId: i + 1, name,
                    icon: templates.find(t => t.businessCategory === name)?.categoryIcon || FALLBACK_ICONS[name] || '📋',
                    isActive: true,
                    templateCount: templates.filter(t => t.businessCategory === name).length,
                })));
            }

            if (objData?.ok && objData.objectives) {
                setObjectives([...objData.objectives].sort((a, b) => a.name.localeCompare(b.name)));
            } else {
                const objNames = [...new Set(templates.map(t => t.objective))].sort();
                setObjectives(objNames.map((name, i) => ({
                    objectiveId: i + 1, name,
                    color: templates.find(t => t.objective === name)?.objectiveColor || FALLBACK_OBJ_COLORS[name] || '#999',
                    isActive: true,
                    templateCount: templates.filter(t => t.objective === name).length,
                })));
            }
        } catch (err) {
            console.warn('[Templates] Metadata fetch failed, using fallbacks:', err.message);
            const catNames = [...new Set(templates.map(t => t.businessCategory))].sort();
            setCategories(catNames.map((name, i) => ({
                categoryId: i + 1, name,
                icon: FALLBACK_ICONS[name] || '📋', isActive: true,
                templateCount: templates.filter(t => t.businessCategory === name).length,
            })));
            const objNames = [...new Set(templates.map(t => t.objective))].sort();
            setObjectives(objNames.map((name, i) => ({
                objectiveId: i + 1, name,
                color: FALLBACK_OBJ_COLORS[name] || '#999', isActive: true,
                templateCount: templates.filter(t => t.objective === name).length,
            })));
        } finally {
            setMetaLoading(false);
        }
    }, [sessionToken, templates]);

    useEffect(() => { fetchMetadata(); }, [fetchMetadata]);

    // Auto-select first category
    useEffect(() => {
        if (!selectedCategory && categories.length > 0) {
            setSelectedCategory(categories[0].name);
        }
    }, [categories, selectedCategory]);

    // ─── Memoized lookups ───────────────────────────────────
    const catIconMap = useMemo(() => {
        const map = {};
        categories.forEach(c => { map[c.name] = c.icon; });
        return map;
    }, [categories]);

    const objColorMap = useMemo(() => {
        const map = {};
        objectives.forEach(o => { map[o.name] = o.color; });
        return map;
    }, [objectives]);

    const filtered = useMemo(() =>
        templates.filter(t =>
            (!selectedCategory || t.businessCategory === selectedCategory) &&
            (!selectedObjective || t.objective === selectedObjective)
        ),
        [templates, selectedCategory, selectedObjective]
    );

    const grouped = useMemo(() => {
        const g = {};
        filtered.forEach(t => {
            const key = `${t.businessCategory}|${t.objective}`;
            if (!g[key]) g[key] = [];
            g[key].push(t);
        });
        return g;
    }, [filtered]);

    const catCounts = useMemo(() => {
        const counts = {};
        templates.forEach(t => {
            counts[t.businessCategory] = (counts[t.businessCategory] || 0) + 1;
        });
        return counts;
    }, [templates]);

    // ─── CRUD operations ────────────────────────────────────
    const handleUpdateCategory = useCallback(async (categoryId, updates) => {
        const result = await apiCall(`/api/admin/template-config/categories/${categoryId}`, 'PUT', updates);
        if (result.ok) { fetchMetadata(); refresh(); }
        else alert(result.error || 'Update failed');
    }, [apiCall, fetchMetadata, refresh]);

    const handleDeleteCategory = useCallback(async (categoryId, name) => {
        if (!confirm(`Delete category "${name}"? This cannot be undone.`)) return;
        const result = await apiCall(`/api/admin/template-config/categories/${categoryId}`, 'DELETE');
        if (result.ok) {
            if (selectedCategory === name) setSelectedCategory(null);
            fetchMetadata(); refresh();
        }
        else alert(result.error || 'Delete failed');
    }, [apiCall, fetchMetadata, refresh, selectedCategory]);

    const handleCreateCategory = useCallback(async () => {
        if (!newCatName.trim()) return;
        const result = await apiCall('/api/admin/template-config/categories', 'POST', {
            name: newCatName.trim().toLowerCase().replace(/\s+/g, '_'),
            icon: newCatIcon || '📋',
        });
        if (result.ok) {
            setNewCatName(''); setNewCatIcon(''); setShowNewCat(false);
            fetchMetadata();
        }
        else alert(result.error || 'Create failed');
    }, [apiCall, fetchMetadata, newCatName, newCatIcon]);

    const handleUpdateObjective = useCallback(async (objectiveId, updates) => {
        const result = await apiCall(`/api/admin/template-config/objectives/${objectiveId}`, 'PUT', updates);
        if (result.ok) fetchMetadata();
        else alert(result.error || 'Update failed');
    }, [apiCall, fetchMetadata]);

    const handleDeleteTemplate = useCallback(async (templateId) => {
        if (!confirm('Delete this allocation template?')) return;
        const result = await apiCall(`/api/admin/templates/${templateId}`, 'DELETE');
        if (result.ok) refresh();
        else alert(result.error || 'Delete failed');
    }, [apiCall, refresh]);

    // ─── Memoized context value ─────────────────────────────
    const value = useMemo(() => ({
        // Data
        templates, categories, objectives, metaLoading,
        catIconMap, objColorMap, catCounts,
        filtered, grouped,

        // Sidebar state
        selectedCategory, setSelectedCategory,
        selectedObjective, setSelectedObjective,
        editMode, setEditMode,

        // Form state
        showForm, setShowForm,
        editingId, setEditingId,
        addingToGroup, setAddingToGroup,

        // New category
        showNewCat, setShowNewCat,
        newCatName, setNewCatName,
        newCatIcon, setNewCatIcon,

        // Actions
        fetchMetadata,
        handleUpdateCategory, handleDeleteCategory, handleCreateCategory,
        handleUpdateObjective, handleDeleteTemplate,
    }), [
        templates, categories, objectives, metaLoading,
        catIconMap, objColorMap, catCounts,
        filtered, grouped,
        selectedCategory, selectedObjective, editMode,
        showForm, editingId, addingToGroup,
        showNewCat, newCatName, newCatIcon,
        fetchMetadata,
        handleUpdateCategory, handleDeleteCategory, handleCreateCategory,
        handleUpdateObjective, handleDeleteTemplate,
    ]);

    return <TemplatesContext.Provider value={value}>{children}</TemplatesContext.Provider>;
}
