import { useState, useEffect } from "react";
import { FolderOpen, RefreshCw, Plus } from "lucide-react";
import { CustomSkill, SkillParameter } from "../../shared/types";
import { getEmojiIcon } from "../utils/emoji-icon-map";

interface SkillsSettingsProps {
  onSkillSelect?: (skill: CustomSkill) => void;
}

export function SkillsSettings({ onSkillSelect }: SkillsSettingsProps) {
  const [skills, setSkills] = useState<CustomSkill[]>([]);
  const [externalSkillDirectories, setExternalSkillDirectories] = useState<string[]>([]);
  const [externalSkillDirectoryInput, setExternalSkillDirectoryInput] = useState("");
  const [loading, setLoading] = useState(true);
  const [editingSkill, setEditingSkill] = useState<CustomSkill | null>(null);
  const [isCreating, setIsCreating] = useState(false);
  const [error, setError] = useState<string | null>(null);

  // Load skills on mount
  useEffect(() => {
    loadSkills();
  }, []);

  const loadSkills = async () => {
    try {
      setLoading(true);
      const [loadedSkills, settings] = await Promise.all([
        window.electronAPI.listCustomSkills(),
        window.electronAPI.getCustomSkillSettings(),
      ]);
      setSkills(loadedSkills);
      setExternalSkillDirectories(settings.externalSkillDirectories || []);
      setError(null);
    } catch (err) {
      setError("Failed to load skills");
      console.error("Failed to load skills:", err);
    } finally {
      setLoading(false);
    }
  };

  const handleReload = async () => {
    try {
      const reloadedSkills = await window.electronAPI.reloadCustomSkills();
      setSkills(reloadedSkills);
      setError(null);
    } catch  {
      setError("Failed to reload skills");
    }
  };

  const handleOpenFolder = async () => {
    await window.electronAPI.openCustomSkillsFolder();
  };

  const handleAddExternalDirectory = async () => {
    const nextDir = externalSkillDirectoryInput.trim();
    if (!nextDir) return;

    try {
      const settings = await window.electronAPI.setExternalSkillDirectories([
        ...externalSkillDirectories,
        nextDir,
      ]);
      setExternalSkillDirectories(settings.externalSkillDirectories || []);
      setExternalSkillDirectoryInput("");
      await loadSkills();
    } catch (err: Any) {
      setError(err?.message || "Failed to add external skill directory");
    }
  };

  const handleRemoveExternalDirectory = async (dir: string) => {
    try {
      const settings = await window.electronAPI.setExternalSkillDirectories(
        externalSkillDirectories.filter((entry) => entry !== dir),
      );
      setExternalSkillDirectories(settings.externalSkillDirectories || []);
      await loadSkills();
    } catch (err: Any) {
      setError(err?.message || "Failed to remove external skill directory");
    }
  };

  const handleOpenExternalDirectory = async (dir: string) => {
    try {
      await window.electronAPI.openExternalSkillFolder(dir);
    } catch (err: Any) {
      setError(err?.message || "Failed to open external skill directory");
    }
  };

  const handleDelete = async (id: string) => {
    if (!confirm("Are you sure you want to delete this skill?")) return;

    try {
      await window.electronAPI.deleteCustomSkill(id);
      setSkills((prev) => prev.filter((s) => s.id !== id));
    } catch  {
      setError("Failed to delete skill");
    }
  };

  const handleEdit = (skill: CustomSkill) => {
    setEditingSkill({ ...skill });
    setIsCreating(false);
  };

  const handleCreate = () => {
    setEditingSkill({
      id: "",
      name: "",
      description: "",
      icon: "⚡",
      prompt: "",
      category: "",
      enabled: true,
      parameters: [],
    });
    setIsCreating(true);
  };

  const handleSave = async () => {
    if (!editingSkill) return;

    try {
      if (isCreating) {
        const created = await window.electronAPI.createCustomSkill(editingSkill);
        setSkills((prev) => [...prev, created]);
      } else {
        const updated = await window.electronAPI.updateCustomSkill(editingSkill.id, editingSkill);
        setSkills((prev) => prev.map((s) => (s.id === updated.id ? updated : s)));
      }
      setEditingSkill(null);
      setIsCreating(false);
      setError(null);
    } catch (err: Any) {
      setError(err.message || "Failed to save skill");
    }
  };

  const handleCancel = () => {
    setEditingSkill(null);
    setIsCreating(false);
  };

  // Group skills by category
  const groupedSkills = skills.reduce(
    (acc, skill) => {
      const category = skill.category || "Uncategorized";
      if (!acc[category]) acc[category] = [];
      acc[category].push(skill);
      return acc;
    },
    {} as Record<string, CustomSkill[]>,
  );

  if (loading) {
    return <div className="settings-loading">Loading skills...</div>;
  }

  // Edit/Create form
  if (editingSkill) {
    return (
      <SkillEditor
        skill={editingSkill}
        isCreating={isCreating}
        onChange={setEditingSkill}
        onSave={handleSave}
        onCancel={handleCancel}
        error={error}
      />
    );
  }

  return (
    <div className="skills-settings">
      <div className="settings-section">
        <div className="settings-section-header">
          <h3>Custom Skills</h3>
          <div className="settings-section-actions">
            <button className="btn-secondary btn-sm" onClick={handleOpenFolder}>
              <FolderOpen size={14} strokeWidth={2} />
              Open Folder
            </button>
            <button className="btn-secondary btn-sm" onClick={handleReload}>
              <RefreshCw size={14} strokeWidth={2} />
              Reload
            </button>
            <button className="btn-primary btn-sm" onClick={handleCreate}>
              <Plus size={14} strokeWidth={2} />
              New Skill
            </button>
          </div>
        </div>
        <p className="settings-description">
          Create custom prompt templates for things we do often. Skills are stored as JSON files and
          can be shared or version controlled.
        </p>
        <div className="form-group">
          <label>External Skill Directories</label>
          <div className="settings-section-actions">
            <input
              type="text"
              value={externalSkillDirectoryInput}
              onChange={(e) => setExternalSkillDirectoryInput(e.target.value)}
              placeholder="/absolute/path/to/shared/skills"
            />
            <button className="btn-secondary btn-sm" onClick={handleAddExternalDirectory}>
              Add Directory
            </button>
          </div>
          <p className="form-hint">
            External directories are loaded read-only. Managed installs still go to the main CoWork
            skills folder and take precedence over these shared paths.
          </p>
          {externalSkillDirectories.length > 0 && (
            <div className="parameters-list">
              {externalSkillDirectories.map((dir) => (
                <div key={dir} className="parameter-item">
                  <div className="parameter-main">
                    <div className="parameter-row">
                      <input type="text" value={dir} readOnly />
                    </div>
                  </div>
                  <div className="parameter-actions">
                    <button
                      className="btn-secondary btn-xs"
                      onClick={() => handleOpenExternalDirectory(dir)}
                    >
                      Open
                    </button>
                    <button
                      className="btn-danger btn-xs"
                      onClick={() => handleRemoveExternalDirectory(dir)}
                    >
                      Remove
                    </button>
                  </div>
                </div>
              ))}
            </div>
          )}
        </div>
      </div>

      {error && <div className="settings-error">{error}</div>}

      {skills.length === 0 ? (
        <div className="skills-empty">
          <p>No custom skills found.</p>
          <p>
            Click "New Skill" to create your first skill, or "Open Folder" to add skill JSON files
            manually.
          </p>
        </div>
      ) : (
        <div className="skills-list">
          {Object.entries(groupedSkills).map(([category, categorySkills]) => (
            <div key={category} className="skills-category">
              <h4 className="skills-category-title">{category}</h4>
              <div className="skills-grid">
                {categorySkills.map((skill) => (
                  <div
                    key={skill.id}
                    className={`skill-card ${skill.type === "guideline" ? "skill-card-guideline" : ""}`}
                  >
                    <div className="skill-card-header">
                      <span className="skill-icon">
                        {(() => {
                          const Icon = getEmojiIcon(skill.icon);
                          return <Icon size={18} strokeWidth={1.5} />;
                        })()}
                      </span>
                      <div className="skill-info">
                        <span className="skill-name">
                          {skill.name}
                          {skill.source && (
                            <span className="skill-type-badge">{skill.source}</span>
                          )}
                          {skill.type === "guideline" && (
                            <span className="skill-type-badge">Behavior</span>
                          )}
                        </span>
                        <span className="skill-description">{skill.description}</span>
                      </div>
                      {skill.type === "guideline" &&
                        skill.source !== "bundled" &&
                        skill.source !== "external" && (
                        <label className="settings-toggle">
                          <input
                            type="checkbox"
                            checked={skill.enabled !== false}
                            onChange={async (e) => {
                              try {
                                const updated = await window.electronAPI.updateCustomSkill(
                                  skill.id,
                                  { enabled: e.target.checked },
                                );
                                setSkills((prev) =>
                                  prev.map((s) => (s.id === updated.id ? updated : s)),
                                );
                              } catch (err) {
                                console.error("Failed to toggle skill:", err);
                              }
                            }}
                          />
                          <span className="toggle-slider"></span>
                        </label>
                      )}
                    </div>
                    <div className="skill-card-actions">
                      {onSkillSelect && skill.type !== "guideline" && (
                        <button className="btn-primary btn-xs" onClick={() => onSkillSelect(skill)}>
                          Use
                        </button>
                      )}
                      {skill.source !== "bundled" && skill.source !== "external" && (
                        <button className="btn-secondary btn-xs" onClick={() => handleEdit(skill)}>
                          Edit
                        </button>
                      )}
                      {skill.source !== "bundled" && skill.source !== "external" && (
                        <button className="btn-danger btn-xs" onClick={() => handleDelete(skill.id)}>
                          Delete
                        </button>
                      )}
                    </div>
                  </div>
                ))}
              </div>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

// Skill Editor Component
interface SkillEditorProps {
  skill: CustomSkill;
  isCreating: boolean;
  onChange: (skill: CustomSkill) => void;
  onSave: () => void;
  onCancel: () => void;
  error: string | null;
}

function SkillEditor({ skill, isCreating, onChange, onSave, onCancel, error }: SkillEditorProps) {
  const updateField = <K extends keyof CustomSkill>(field: K, value: CustomSkill[K]) => {
    onChange({ ...skill, [field]: value });
  };

  const addParameter = () => {
    const newParam: SkillParameter = {
      name: "",
      type: "string",
      description: "",
      required: false,
    };
    onChange({ ...skill, parameters: [...(skill.parameters || []), newParam] });
  };

  const updateParameter = (index: number, updates: Partial<SkillParameter>) => {
    const params = [...(skill.parameters || [])];
    params[index] = { ...params[index], ...updates };
    onChange({ ...skill, parameters: params });
  };

  const removeParameter = (index: number) => {
    const params = [...(skill.parameters || [])];
    params.splice(index, 1);
    onChange({ ...skill, parameters: params });
  };

  return (
    <div className="skill-editor">
      <div className="settings-section">
        <h3>{isCreating ? "Create New Skill" : "Edit Skill"}</h3>
      </div>

      {error && <div className="settings-error">{error}</div>}

      <div className="skill-editor-form">
        <div className="form-row">
          <div className="form-group form-group-icon">
            <label>Icon</label>
            <input
              type="text"
              value={skill.icon}
              onChange={(e) => updateField("icon", e.target.value)}
              placeholder="⚡"
              maxLength={2}
            />
          </div>
          <div className="form-group form-group-flex">
            <label>Name *</label>
            <input
              type="text"
              value={skill.name}
              onChange={(e) => updateField("name", e.target.value)}
              placeholder="My Custom Skill"
            />
          </div>
        </div>

        <div className="form-row">
          <div className="form-group form-group-flex">
            <label>Category</label>
            <input
              type="text"
              value={skill.category || ""}
              onChange={(e) => updateField("category", e.target.value)}
              placeholder="Development, Documentation, etc."
            />
          </div>
        </div>

        <div className="form-group">
          <label>Description *</label>
          <input
            type="text"
            value={skill.description}
            onChange={(e) => updateField("description", e.target.value)}
            placeholder="What does this skill do?"
          />
        </div>

        <div className="form-group">
          <label>Prompt Template *</label>
          <textarea
            value={skill.prompt}
            onChange={(e) => updateField("prompt", e.target.value)}
            placeholder="Enter the prompt template. Use {{parameterName}} for placeholders."
            rows={8}
          />
          <p className="form-hint">
            Use {"{{parameterName}}"} syntax to insert parameter values into the prompt.
          </p>
        </div>

        <div className="form-section">
          <div className="form-section-header">
            <h4>Parameters</h4>
            <button className="btn-secondary btn-xs" onClick={addParameter}>
              + Add Parameter
            </button>
          </div>

          {(skill.parameters || []).length === 0 ? (
            <p className="form-hint">
              No parameters defined. Add parameters to make your skill configurable.
            </p>
          ) : (
            <div className="parameters-list">
              {(skill.parameters || []).map((param, index) => (
                <div key={index} className="parameter-item">
                  <div className="parameter-row">
                    <div className="form-group form-group-sm">
                      <label>Name</label>
                      <input
                        type="text"
                        value={param.name}
                        onChange={(e) => updateParameter(index, { name: e.target.value })}
                        placeholder="paramName"
                      />
                    </div>
                    <div className="form-group form-group-sm">
                      <label>Type</label>
                      <select
                        value={param.type}
                        onChange={(e) =>
                          updateParameter(index, { type: e.target.value as SkillParameter["type"] })
                        }
                      >
                        <option value="string">String</option>
                        <option value="number">Number</option>
                        <option value="boolean">Boolean</option>
                        <option value="select">Select</option>
                      </select>
                    </div>
                    <div className="form-group form-group-sm">
                      <label>Required</label>
                      <input
                        type="checkbox"
                        checked={param.required || false}
                        onChange={(e) => updateParameter(index, { required: e.target.checked })}
                      />
                    </div>
                    <button className="btn-danger btn-xs" onClick={() => removeParameter(index)}>
                      Remove
                    </button>
                  </div>
                  <div className="parameter-row">
                    <div className="form-group form-group-flex">
                      <label>Description</label>
                      <input
                        type="text"
                        value={param.description}
                        onChange={(e) => updateParameter(index, { description: e.target.value })}
                        placeholder="What is this parameter for?"
                      />
                    </div>
                    <div className="form-group form-group-sm">
                      <label>Default</label>
                      <input
                        type="text"
                        value={String(param.default || "")}
                        onChange={(e) => updateParameter(index, { default: e.target.value })}
                        placeholder="Default value"
                      />
                    </div>
                  </div>
                  {param.type === "select" && (
                    <div className="parameter-row">
                      <div className="form-group form-group-flex">
                        <label>Options (comma-separated)</label>
                        <input
                          type="text"
                          value={(param.options || []).join(", ")}
                          onChange={(e) =>
                            updateParameter(index, {
                              options: e.target.value
                                .split(",")
                                .map((s) => s.trim())
                                .filter(Boolean),
                            })
                          }
                          placeholder="option1, option2, option3"
                        />
                      </div>
                    </div>
                  )}
                </div>
              ))}
            </div>
          )}
        </div>
      </div>

      <div className="skill-editor-actions">
        <button className="btn-secondary" onClick={onCancel}>
          Cancel
        </button>
        <button
          className="btn-primary"
          onClick={onSave}
          disabled={!skill.name || !skill.description || !skill.prompt}
        >
          {isCreating ? "Create Skill" : "Save Changes"}
        </button>
      </div>
    </div>
  );
}
