import { useState, useEffect } from "react";
import { useApp } from "../state/store";
import { wizardApi, type BatchOperation } from "../lib/wizardApi";
import { Branch, Check, Close, ChevronRight } from "../components/icons";

type WizardStep = "Intake" | "Analyze" | "Generate" | "Validate" | "Draft saved" | "Publish";

const STEPS: WizardStep[] = ["Intake", "Analyze", "Generate", "Validate", "Draft saved", "Publish"];

interface DraftState {
  step: WizardStep;
  flowKey?: string;
  name: string;
  description: string;
  nodes: any[];
  edges: any[];
  fields: { name: string; type: string }[];
  rules: string[];
}

export default function Wizard() {
  const mode = useApp((s) => s.mode);
  const pushToast = useApp((s) => s.pushToast);
  const refreshLive = useApp((s) => s.refreshLive);
  const actor = useApp((s) => s.actor);
  const setScene = useApp((s) => s.setScene);

  const canPublish = mode === "live" && !!actor?.user_id;

  const [draft, setDraft] = useState<DraftState>(() => {
    try {
      const stored = localStorage.getItem("fm.mc.wizard.draft");
      if (stored) return JSON.parse(stored);
    } catch {}
    return {
      step: "Intake",
      name: "",
      description: "",
      nodes: [],
      edges: [],
      fields: [],
      rules: []
    };
  });

  const [working, setWorking] = useState(false);
  const [publishedKey, setPublishedKey] = useState<string | null>(null);

  useEffect(() => {
    localStorage.setItem("fm.mc.wizard.draft", JSON.stringify(draft));
  }, [draft]);

  const updateDraft = (patch: Partial<DraftState>) => {
    setDraft(d => ({ ...d, ...patch }));
  };

  const handleIntakeSubmit = async () => {
    if (!draft.description) return;
    setWorking(true);
    try {
      const slug = `process_${Date.now()}`;
      const res = await wizardApi.createDraft({
        name: slug,
        display_name: draft.name || "Untitled Process",
        description: draft.description,
        source_context: "EA2_DRAFT_PROCESS:process_creation",
        config: {
          wizard: {
            marker: "EA2_DRAFT_PROCESS",
            maxDepth: 5,
            maxNodes: 40,
            chat: [],
            uploads: [],
            panelState: {},
            debug: []
          }
        }
      });
      
      // Auto-generate basic 5-step template
      const templateNodes = [
        { _key: "n1", kind: "step", display_name: "Capture request details", dispatch_kind: "human" },
        { _key: "n2", kind: "step", display_name: "Validate requirements", dispatch_kind: "agent", agent_capability: "evaluate_business_rule" },
        { _key: "n3", kind: "step", display_name: "Prepare work package", dispatch_kind: "agent", agent_capability: "process_design_assistant" },
        { _key: "n4", kind: "step", display_name: "Review and approve", dispatch_kind: "human" },
        { _key: "n5", kind: "step", display_name: "Close out process", dispatch_kind: "human" }
      ];
      
      updateDraft({ 
        flowKey: res._key, 
        step: "Analyze",
        nodes: templateNodes 
      });
      pushToast("ok", "Draft created in EA2");
    } catch (err: any) {
      pushToast("err", `Failed to create draft: ${err.message}`);
    } finally {
      setWorking(false);
    }
  };

  const handleStructureSave = async () => {
    if (!draft.flowKey || !actor) return;
    setWorking(true);
    try {
      const stepCreateOps: BatchOperation[] = draft.nodes.map(n =>
        wizardApi.ops.createStep({
          display_name: n.display_name,
          dispatch_kind: n.dispatch_kind,
          agent_capability: n.agent_capability,
        })
      );
      const viewCreateOps: BatchOperation[] = draft.nodes.map(n =>
        wizardApi.ops.createView({ display_name: n.display_name })
      );
      const versionCreateOp: BatchOperation = wizardApi.ops.createVersion(draft.name || "Process");
      const allCreateOps = [...stepCreateOps, ...viewCreateOps, versionCreateOp];

      const createRes = await wizardApi.applyBatch(draft.flowKey, allCreateOps, actor);
      const createdOps: any[] = createRes?.result?.ops || [];
      const stepKeys = createdOps.slice(0, draft.nodes.length).map(o => o.key);
      const viewKeys = createdOps.slice(draft.nodes.length, draft.nodes.length * 2).map(o => o.key);
      const versionKey = createdOps[createdOps.length - 1]?.key;
      const nodesWithKeys = draft.nodes.map((n, i) => ({ ...n, _key: stepKeys[i] || n._key, viewKey: viewKeys[i] }));

      const wireOps: BatchOperation[] = [
        ...nodesWithKeys.map((n, _i) => wizardApi.ops.childEdge(draft.flowKey!, n._key)),
        ...nodesWithKeys.map(n => wizardApi.ops.dispatchEdge(n._key)),
        ...nodesWithKeys.map(n => wizardApi.ops.presentationEdge(n._key, n.viewKey)),
      ];
      if (versionKey) wireOps.push(wizardApi.ops.governsEdge(versionKey, draft.flowKey!));
      if (wireOps.length) await wizardApi.applyBatch(draft.flowKey, wireOps, actor);

      updateDraft({ step: "Generate", nodes: nodesWithKeys });
      pushToast("ok", `Saved ${stepKeys.length} steps with views and version to EA2`);
    } catch (err: any) {
      pushToast("err", `Save failed: ${err.message}`);
    } finally {
      setWorking(false);
    }
  };

  const handleDataSave = async () => {
    if (!draft.flowKey || !actor) return;
    setWorking(true);
    try {
      await wizardApi.updateDraftConfig(draft.flowKey, {
         config: { wizard: { panelState: { fields: draft.fields } } }
      });

      if (draft.fields.length > 0 && draft.nodes.length > 0) {
        const replaceOps: BatchOperation[] = draft.nodes.map(n =>
          wizardApi.ops.createView({ display_name: n.display_name, fields: draft.fields })
        );
        const res = await wizardApi.applyBatch(draft.flowKey, replaceOps, actor);
        const newViewKeys = (res?.result?.ops || []).map((o: any) => o.key);
        const wireOps: BatchOperation[] = draft.nodes.map((n, i) =>
          wizardApi.ops.presentationEdge(n._key, newViewKeys[i])
        );
        if (wireOps.length) await wizardApi.applyBatch(draft.flowKey, wireOps, actor);
        updateDraft({ nodes: draft.nodes.map((n, i) => ({ ...n, viewKey: newViewKeys[i] })) });
      }

      updateDraft({ step: "Validate" });
      pushToast("ok", `Saved ${draft.fields.length} fields onto every step's form`);
    } catch (err: any) {
      pushToast("err", `Save failed: ${err.message}`);
    } finally {
      setWorking(false);
    }
  };

  const handleRulesSave = async () => {
    if (!draft.flowKey || !actor) return;
    setWorking(true);
    try {
       await wizardApi.updateDraftConfig(draft.flowKey, {
         config: { wizard: { panelState: { rules: draft.rules } } }
      });
      updateDraft({ step: "Draft saved" });
      pushToast("ok", "Rules saved");
    } catch (err: any) {
      pushToast("err", `Save failed: ${err.message}`);
    } finally {
      setWorking(false);
    }
  };

  const handlePublish = async () => {
    if (!draft.flowKey || !actor) return;
    setWorking(true);
    try {
      const ops: BatchOperation[] = [wizardApi.ops.publishFlow(draft.flowKey)];
      await wizardApi.applyBatch(draft.flowKey, ops, actor);
      updateDraft({ step: "Publish" });
      setPublishedKey(draft.flowKey);
      pushToast("ok", "Process published successfully!");
      refreshLive();
    } catch (err: any) {
      pushToast("err", `Publish failed: ${err.message}`);
    } finally {
      setWorking(false);
    }
  };
  
  const handleStartInstance = async () => {
    if(!publishedKey) return;
    setWorking(true);
    try {
        await wizardApi.startInstance(publishedKey);
        pushToast("ok", "New instance started!");
        setScene("mission");
    } catch(err:any) {
        pushToast("err", `Failed to start: ${err.message}`);
    } finally {
        setWorking(false);
    }
  }

  const renderStepNav = () => (
    <div className="wizard-progress">
      {STEPS.map((step, i) => {
        const isActive = step === draft.step;
        const isPast = STEPS.indexOf(step) < STEPS.indexOf(draft.step);
        return (
          <div key={step} className={`wizard-step-marker ${isActive ? 'active' : ''} ${isPast ? 'past' : ''}`}>
            <span className="step-num">{i + 1}</span>
            <span className="step-label">{step}</span>
            {i < STEPS.length - 1 && <ChevronRight size={12} className="step-chevron" />}
          </div>
        );
      })}
    </div>
  );

  return (
    <div className="wizard-container">
      <header className="wizard-header">
         <div>
          <div className="mc-hero-eyebrow"><Branch size={12} /> Process Creation Wizard</div>
          <h2 className="mc-hero-title">Build a new process</h2>
        </div>
        {renderStepNav()}
      </header>

      <div className="wizard-content">
        {draft.step === "Intake" && (
          <div className="wizard-panel">
            <h3 className="panel-h">What process do you want to build?</h3>
            <div className="field-group">
                <label>Name (optional)</label>
                <input 
                  type="text" 
                  value={draft.name} 
                  onChange={e => updateDraft({ name: e.target.value })} 
                  placeholder="e.g. Laptop Procurement"
                />
            </div>
            <div className="field-group">
                <label>Describe the process</label>
                <textarea 
                  value={draft.description} 
                  onChange={e => updateDraft({ description: e.target.value })}
                  placeholder="When a store manager requests a new laptop, run a procurement approval..."
                  rows={4}
                />
            </div>
            <button 
                className="btn btn-primary" 
                onClick={handleIntakeSubmit} 
                disabled={!draft.description || working || !canPublish}
                title="POST /api/ea2/flow"
            >
              {working ? 'Saving...' : 'Start Drafting →'}
            </button>
            {!canPublish && <p className="warning-text">Switch to LIVE mode + sign in to create processes.</p>}
          </div>
        )}

        {draft.step === "Analyze" && (
          <div className="wizard-panel">
            <h3 className="panel-h">Review proposed structure</h3>
            <div className="node-list">
              {draft.nodes.map((n, i) => (
                <div key={n._key} className="node-card">
                  <div className="node-header">
                    <span className="node-idx">{i + 1}</span>
                    <input 
                      value={n.display_name} 
                      onChange={e => {
                        const newNodes = [...draft.nodes];
                        newNodes[i].display_name = e.target.value;
                        updateDraft({ nodes: newNodes });
                      }}
                    />
                  </div>
                  <div className="node-meta">
                    <select 
                      value={n.dispatch_kind}
                      onChange={e => {
                        const newNodes = [...draft.nodes];
                        newNodes[i].dispatch_kind = e.target.value;
                        updateDraft({ nodes: newNodes });
                      }}
                    >
                      <option value="human">Human Task</option>
                      <option value="agent">Agent Task</option>
                      <option value="system">System Task</option>
                    </select>
                  </div>
                </div>
              ))}
            </div>
            <button 
                className="btn btn-primary" 
                onClick={handleStructureSave} 
                disabled={working}
                title="POST /api/ea2/apply-batch"
            >
              {working ? 'Saving...' : 'Confirm Structure →'}
            </button>
          </div>
        )}

        {draft.step === "Generate" && (
          <div className="wizard-panel">
            <h3 className="panel-h">What information do you need to collect?</h3>
            <div className="field-list">
                {draft.fields.map((f, i) => (
                    <div key={i} className="field-row">
                        <input 
                            placeholder="Field name" 
                            value={f.name} 
                            onChange={e => {
                                const newFields = [...draft.fields];
                                newFields[i].name = e.target.value;
                                updateDraft({ fields: newFields });
                            }} 
                        />
                        <select 
                            value={f.type}
                            onChange={e => {
                                const newFields = [...draft.fields];
                                newFields[i].type = e.target.value;
                                updateDraft({ fields: newFields });
                            }}
                        >
                            <option value="string">Text</option>
                            <option value="number">Number</option>
                            <option value="boolean">Yes/No</option>
                        </select>
                        <button className="icon-btn" onClick={() => updateDraft({ fields: draft.fields.filter((_, idx) => idx !== i) })}><Close size={12} /></button>
                    </div>
                ))}
                <button className="btn btn-secondary" onClick={() => updateDraft({ fields: [...draft.fields, { name: "", type: "string" }] })}>+ Add Field</button>
            </div>
            <button 
                className="btn btn-primary" 
                onClick={handleDataSave} 
                disabled={working}
                title="PUT /api/ea2/flow/{key}"
            >
              {working ? 'Saving...' : 'Confirm Data →'}
            </button>
          </div>
        )}

        {draft.step === "Validate" && (
           <div className="wizard-panel">
            <h3 className="panel-h">When should this process do something different? (Rules)</h3>
             <div className="field-list">
                {draft.rules.map((r, i) => (
                    <div key={i} className="field-row">
                        <input 
                            placeholder="e.g. If cost > 5000, require VP approval" 
                            value={r} 
                            onChange={e => {
                                const newRules = [...draft.rules];
                                newRules[i] = e.target.value;
                                updateDraft({ rules: newRules });
                            }} 
                            style={{ flex: 1 }}
                        />
                         <button className="icon-btn" onClick={() => updateDraft({ rules: draft.rules.filter((_, idx) => idx !== i) })}><Close size={12} /></button>
                    </div>
                ))}
                 <button className="btn btn-secondary" onClick={() => updateDraft({ rules: [...draft.rules, ""] })}>+ Add Rule</button>
            </div>
             <button 
                className="btn btn-primary" 
                onClick={handleRulesSave} 
                disabled={working}
                title="PUT /api/ea2/flow/{key}"
            >
              {working ? 'Saving...' : 'Review Process →'}
            </button>
          </div>
        )}

        {draft.step === "Draft saved" && (
           <div className="wizard-panel">
            <h3 className="panel-h">Review & Publish</h3>
            <p>Your process <strong>{draft.name || 'Untitled'}</strong> is ready to be published to EA2.</p>
            <div className="summary-stats">
                <div><span>Steps:</span> {draft.nodes.length}</div>
                <div><span>Data fields:</span> {draft.fields.length}</div>
                <div><span>Rules:</span> {draft.rules.length}</div>
            </div>
            <div className="actions-row">
                <button className="btn btn-secondary" onClick={() => updateDraft({ step: "Intake" })}>Edit</button>
                <button 
                    className="btn btn-primary" 
                    onClick={handlePublish} 
                    disabled={working}
                    title="POST /api/ea2/apply-batch"
                >
                {working ? 'Publishing...' : 'Publish to EA2'}
                </button>
            </div>
          </div>
        )}

        {draft.step === "Publish" && (
             <div className="wizard-panel success-panel">
                <div className="success-icon"><Check size={32} /></div>
                <h3 className="panel-h">Process Published!</h3>
                <p>Your process <strong>{draft.name || "Untitled"}</strong> is now active and ready to run.</p>
                <div className="actions-row">
                     <button className="btn btn-secondary" onClick={() => { setDraft({ step: "Intake", name: "", description: "", nodes: [], edges: [], fields: [], rules: [] }); setPublishedKey(null); }}>Create Another</button>
                     <button 
                        className="btn btn-primary" 
                        onClick={handleStartInstance} 
                        disabled={working}
                        title="POST /api/runtime/transactions"
                     >
                        Start First Instance Now
                    </button>
                </div>
             </div>
        )}
      </div>
    </div>
  );
}
