import { useState, useCallback, useMemo } from 'react';
import { useEditorStore } from '../../store/editorStore';
import type { CssRule, CssProperty } from '@shared/types';
import { Plus, Trash2, Palette, FileType, Globe } from 'lucide-react';
import { v4 as uuidv4 } from 'uuid';

function collectSelectorsFromElements(elements: any[]): string[] {
  const selectors = new Set<string>();
  const walk = (els: any[]) => {
    for (const el of els) {
      if (el.props?.id) selectors.add(`#${el.props.id}`);
      if (el.tagName) selectors.add(el.tagName);
      el.classes?.forEach((c: string) => {
        if (c) selectors.add(`.${c}`);
      });
      if (el.children) walk(el.children);
    }
  };
  walk(elements);
  return Array.from(selectors).sort();
}

function rulesToCssText(rules: CssRule[]): string {
  return rules
    .filter((r: CssRule) => r.enabled)
    .map((r: CssRule) => {
      const props = r.properties
        .filter((p: CssProperty) => p.name && p.value)
        .map((p: CssProperty) => {
          const important = p.important ? ' !important' : '';
          return `  ${p.name}: ${p.value}${important};`;
        })
        .join('\n');
      if (!props) return '';
      const media = r.mediaQuery ? `\n@media ${r.mediaQuery} {\n` : '';
      const closeMedia = r.mediaQuery ? '\n}' : '';
      return `${media}${r.selector} {\n${props}\n}${closeMedia}`;
    })
    .filter(Boolean)
    .join('\n\n');
}

export default function CssRulePanel() {
  const {
    activeFileId, fileTree, elementRegistry,
    cssRules, setCssRules, updateFile,
  } = useEditorStore();

  const activeFile = useMemo(
    () => activeFileId ? fileTree.find(f => f.id === activeFileId) : null,
    [activeFileId, fileTree]
  );

  // Get elements from linked HTML files
  const linkedElementSelectors = useMemo(() => {
    if (!activeFileId) return [];
    // Find HTML files that link to this CSS file, or CSS files linked FROM HTML
    const linkingHtmlFiles = fileTree.filter(
      f => f.type === 'html' && (f.linkedFiles || []).includes(activeFileId)
    );
    const selectors = new Set<string>();
    for (const hf of linkingHtmlFiles) {
      const els = elementRegistry[hf.id] || [];
      collectSelectorsFromElements(els).forEach(s => selectors.add(s));
    }
    // Also add selectors from all HTML files as fallback
    const allHtmlFiles = fileTree.filter(f => f.type === 'html');
    for (const hf of allHtmlFiles) {
      const els = elementRegistry[hf.id] || [];
      collectSelectorsFromElements(els).forEach(s => selectors.add(s));
    }
    return Array.from(selectors).sort();
  }, [activeFileId, fileTree, elementRegistry]);

  const rules = useMemo(() => {
    if (!activeFileId) return [];
    return cssRules[activeFileId] || [];
  }, [activeFileId, cssRules]);

  const [expandedRule, setExpandedRule] = useState<string | null>(null);

  const addRule = useCallback(() => {
    if (!activeFileId) return;
    const newRule: CssRule = {
      id: uuidv4(),
      selector: linkedElementSelectors[0] || 'body',
      type: 'class',
      properties: [{ id: uuidv4(), name: 'color', value: '#333', important: false, type: 'standard', unit: '' }],
      enabled: true,
    };
    setCssRules(activeFileId, [...rules, newRule]);
    setExpandedRule(newRule.id);
  }, [activeFileId, linkedElementSelectors, rules, setCssRules]);

  const updateRule = useCallback((ruleId: string, updates: Partial<CssRule>) => {
    if (!activeFileId) return;
    setCssRules(activeFileId, rules.map((r: CssRule) => r.id === ruleId ? { ...r, ...updates } : r));
  }, [activeFileId, rules, setCssRules]);

  const removeRule = useCallback((ruleId: string) => {
    if (!activeFileId) return;
    setCssRules(activeFileId, rules.filter((r: CssRule) => r.id !== ruleId));
  }, [activeFileId, rules, setCssRules]);

  const addProperty = useCallback((ruleId: string) => {
    const rule = rules.find((r: CssRule) => r.id === ruleId);
    if (!rule) return;
    const newProp: CssProperty = { id: uuidv4(), name: '', value: '', important: false, type: 'standard', unit: '' };
    updateRule(ruleId, { properties: [...rule.properties, newProp] });
  }, [rules, updateRule]);

  const updateProperty = useCallback((ruleId: string, propId: string, updates: Partial<CssProperty>) => {
    const rule = rules.find((r: CssRule) => r.id === ruleId);
    if (!rule) return;
    updateRule(ruleId, {
      properties: rule.properties.map((p: CssProperty) => p.id === propId ? { ...p, ...updates } : p),
    });
  }, [rules, updateRule]);

  const removeProperty = useCallback((ruleId: string, propId: string) => {
    const rule = rules.find((r: CssRule) => r.id === ruleId);
    if (!rule) return;
    updateRule(ruleId, { properties: rule.properties.filter((p: CssProperty) => p.id !== propId) });
  }, [rules, updateRule]);

  // Save CSS rules to file content
  const applyToFile = useCallback(() => {
    if (!activeFileId || !activeFile) return;
    const cssText = rulesToCssText(rules);
    updateFile(activeFileId, { content: cssText });
  }, [activeFileId, activeFile, rules, updateFile]);

  if (!activeFile || activeFile.type !== 'css') {
    return (
      <div className="flex items-center justify-center h-full text-surface-500 text-xs p-4">
        Select a CSS file to manage styles
      </div>
    );
  }

  return (
    <div className="flex flex-col h-full">
      <div className="p-3 border-b border-surface-700">
        <div className="flex items-center justify-between mb-2">
          <h3 className="text-xs font-semibold text-surface-300 uppercase tracking-wider flex items-center gap-1.5">
            <FileType className="w-3.5 h-3.5 text-amber-400" />
            CSS Rules
          </h3>
          <div className="flex items-center gap-1">
            <button onClick={applyToFile}
              className="px-2 py-1 text-[10px] bg-primary-600 text-white rounded hover:bg-primary-500">
              Apply to File
            </button>
            <button onClick={addRule}
              className="p-1 text-surface-400 hover:text-primary-400 hover:bg-surface-700 rounded">
              <Plus className="w-3.5 h-3.5" />
            </button>
          </div>
        </div>
        {linkedElementSelectors.length > 0 && (
          <div className="flex flex-wrap gap-1 mb-2">
            <span className="text-[9px] text-surface-500 mr-1 mt-0.5">
              <Globe className="w-2.5 h-2.5 inline mr-0.5" />
              Elements:
            </span>
            {linkedElementSelectors.slice(0, 8).map(sel => (
              <button key={sel}
                onClick={() => setExpandedRule(sel)}
                className="text-[9px] px-1.5 py-0.5 bg-surface-800 text-primary-300 rounded hover:bg-primary-500/20"
              >
                {sel}
              </button>
            ))}
            {linkedElementSelectors.length > 8 && (
              <span className="text-[9px] text-surface-500">+{linkedElementSelectors.length - 8} more</span>
            )}
          </div>
        )}
      </div>

      <div className="flex-1 overflow-y-auto p-2 space-y-2">
        {rules.length === 0 ? (
          <div className="flex flex-col items-center justify-center py-8 text-surface-500">
            <Palette className="w-8 h-8 mb-2 opacity-30" />
            <p className="text-xs">No CSS rules yet</p>
            <p className="text-[10px] mt-1">Click + to add a rule</p>
          </div>
        ) : (
          rules.map(rule => (
            <div key={rule.id} className="border border-surface-700/50 rounded-lg overflow-hidden">
              {/* Rule header */}
              <div className="flex items-center gap-1 px-2 py-1.5 bg-surface-800/50"
                onClick={() => setExpandedRule(expandedRule === rule.id ? null : rule.id)}>
                <input type="text" value={rule.selector}
                  onChange={(e) => updateRule(rule.id, { selector: e.target.value })}
                  onClick={(e) => e.stopPropagation()}
                  className="flex-1 bg-transparent text-xs font-mono text-primary-300 outline-none"
                  placeholder=".my-class" />
                <span className="text-[9px] text-surface-500">{rule.properties.filter((p: CssProperty) => p.name && p.value).length} props</span>
                <button onClick={(e) => { e.stopPropagation(); removeRule(rule.id); }}
                  className="p-0.5 text-red-400 hover:text-red-300 hover:bg-surface-700 rounded">
                  <Trash2 className="w-3 h-3" />
                </button>
              </div>

              {/* Rule properties */}
              {expandedRule === rule.id && (
                <div className="px-2 py-1.5 space-y-1">
                  <div className="flex items-center gap-1 text-[9px] text-surface-500 mb-1">
                    <label className="w-20">Selector</label>
                    <div className="flex flex-wrap gap-1">
                      {linkedElementSelectors.map(sel => (
                        <button key={sel}
                          onClick={() => updateRule(rule.id, { selector: sel })}
                          className={`px-1 py-0.5 rounded text-[9px] transition-colors ${
                            rule.selector === sel ? 'bg-primary-600 text-white' : 'bg-surface-700 text-surface-300 hover:bg-surface-600'
                          }`}>
                          {sel}
                        </button>
                      ))}
                    </div>
                  </div>

                  {rule.properties.map((prop: CssProperty) => (
                    <div key={prop.id} className="flex items-center gap-1 group">
                      <input type="text" value={prop.name}
                        onChange={(e) => updateProperty(rule.id, prop.id, { name: e.target.value })}
                        className="w-24 bg-surface-800 text-[10px] text-surface-200 rounded px-1.5 py-0.5 border border-surface-700 outline-none font-mono"
                        placeholder="property" />
                      <span className="text-surface-500 text-[9px]">:</span>
                      <input type="text" value={prop.value}
                        onChange={(e) => updateProperty(rule.id, prop.id, { value: e.target.value })}
                        className="flex-1 bg-surface-800 text-[10px] text-surface-200 rounded px-1.5 py-0.5 border border-surface-700 outline-none font-mono"
                        placeholder="value" />
                      <button onClick={() => updateProperty(rule.id, prop.id, { important: !prop.important })}
                        className={`text-[9px] px-1 py-0.5 rounded ${prop.important ? 'text-amber-400 bg-amber-500/10' : 'text-surface-600'}`}>
                        !important
                      </button>
                      <button onClick={() => removeProperty(rule.id, prop.id)}
                        className="opacity-0 group-hover:opacity-100 p-0.5 text-red-400 hover:text-red-300">
                        <Trash2 className="w-2.5 h-2.5" />
                      </button>
                    </div>
                  ))}

                  <button onClick={() => addProperty(rule.id)}
                    className="w-full flex items-center gap-1 px-2 py-1 rounded text-[9px] text-surface-500 hover:text-primary-400 hover:bg-surface-800 transition-colors">
                    <Plus className="w-2.5 h-2.5" /> Add property
                  </button>
                </div>
              )}
            </div>
          ))
        )}
      </div>
    </div>
  );
}
