import { useCallback, useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";
import {
  createConfigProfile,
  deleteConfigProfile,
  listConfigProfiles,
  previewConfigProfile,
  updateConfigProfile,
  type ConfigProfile,
  type CreateConfigProfileRequest,
  type ResolvedProfile,
} from "../api/config_profiles";
import { Icon } from "../components/icon";

export const ConfigProfilesPage = () => {
  const navigate = useNavigate();
  const [profiles, setProfiles] = useState<ConfigProfile[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [showForm, setShowForm] = useState(false);
  const [editingProfile, setEditingProfile] = useState<ConfigProfile | null>(null);
  const [previewData, setPreviewData] = useState<ResolvedProfile | null>(null);
  const [previewingId, setPreviewingId] = useState<string | null>(null);

  const [formData, setFormData] = useState<CreateConfigProfileRequest>({
    name: "",
    description: "",
    env_vars: {},
    runtime_hints: {},
    mounts: [],
    files: {},
    is_default: false,
  });

  const loadProfiles = useCallback(async () => {
    try {
      setLoading(true);
      const data = await listConfigProfiles();
      setProfiles(data);
      setError(null);
    } catch {
      setError("Failed to load config profiles");
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => {
    void loadProfiles();
  }, [loadProfiles]);

  const resetForm = () => {
    setFormData({
      name: "",
      description: "",
      env_vars: {},
      runtime_hints: {},
      mounts: [],
      files: {},
      is_default: false,
    });
    setEditingProfile(null);
    setShowForm(false);
  };

  const handleCreate = async (e: React.FormEvent) => {
    e.preventDefault();
    if (!formData.name?.trim()) return;

    try {
      await createConfigProfile(formData);
      resetForm();
      await loadProfiles();
    } catch {
      setError("Failed to create config profile");
    }
  };

  const handleUpdate = async (e: React.FormEvent) => {
    e.preventDefault();
    if (!editingProfile || !formData.name?.trim()) return;

    try {
      await updateConfigProfile(editingProfile.id, formData);
      resetForm();
      await loadProfiles();
    } catch {
      setError("Failed to update config profile");
    }
  };

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

    try {
      await deleteConfigProfile(id);
      await loadProfiles();
    } catch {
      setError("Failed to delete config profile");
    }
  };

  const startEdit = (profile: ConfigProfile) => {
    setEditingProfile(profile);
    setFormData({
      name: profile.name,
      description: profile.description || undefined,
      project_id: profile.project_id || undefined,
      tool_type_id: profile.tool_type_id || undefined,
      env_vars: profile.env_vars,
      runtime_hints: profile.runtime_hints,
      mounts: profile.mounts,
      files: profile.files,
      is_default: profile.is_default,
    });
    setShowForm(true);
    setPreviewData(null);
    setPreviewingId(null);
  };

  const handlePreview = async (id: string) => {
    try {
      setPreviewingId(id);
      const data = await previewConfigProfile(id);
      setPreviewData(data);
    } catch {
      setError("Failed to preview config profile");
    } finally {
      setPreviewingId(null);
    }
  };

  const updateFormField = <K extends keyof CreateConfigProfileRequest>(
    key: K,
    value: CreateConfigProfileRequest[K]
  ) => {
    setFormData((prev) => ({ ...prev, [key]: value }));
  };

  const addEnvVar = () => {
    setFormData((prev) => ({
      ...prev,
      env_vars: { ...prev.env_vars, "": "" },
    }));
  };

  const updateEnvVar = (oldKey: string, newKey: string, value: string) => {
    setFormData((prev) => {
      const envVars = { ...prev.env_vars };
      if (oldKey !== newKey) {
        delete envVars[oldKey];
      }
      envVars[newKey] = value;
      return { ...prev, env_vars: envVars };
    });
  };

  const removeEnvVar = (key: string) => {
    setFormData((prev) => {
      const envVars = { ...prev.env_vars };
      delete envVars[key];
      return { ...prev, env_vars: envVars };
    });
  };

  const addFile = () => {
    setFormData((prev) => ({
      ...prev,
      files: { ...prev.files, "": "" },
    }));
  };

  const updateFile = (oldPath: string, newPath: string, content: string) => {
    setFormData((prev) => {
      const files = { ...prev.files };
      if (oldPath !== newPath) {
        delete files[oldPath];
      }
      files[newPath] = content;
      return { ...prev, files };
    });
  };

  const removeFile = (path: string) => {
    setFormData((prev) => {
      const files = { ...prev.files };
      delete files[path];
      return { ...prev, files };
    });
  };

  const addMount = () => {
    setFormData((prev) => ({
      ...prev,
      mounts: [...(prev.mounts || []), { target: "/", mode: "rw", files: {} }],
    }));
  };

  const updateMount = (index: number, updates: Partial<ConfigProfile["mounts"][0]>) => {
    setFormData((prev) => {
      const mounts = [...(prev.mounts || [])];
      mounts[index] = { ...mounts[index], ...updates };
      return { ...prev, mounts };
    });
  };

  const removeMount = (index: number) => {
    setFormData((prev) => {
      const mounts = [...(prev.mounts || [])];
      mounts.splice(index, 1);
      return { ...prev, mounts };
    });
  };

  const addMountFile = (mountIndex: number) => {
    setFormData((prev) => {
      const mounts = [...(prev.mounts || [])];
      mounts[mountIndex] = {
        ...mounts[mountIndex],
        files: { ...mounts[mountIndex].files, "": "" },
      };
      return { ...prev, mounts };
    });
  };

  const updateMountFile = (
    mountIndex: number,
    oldPath: string,
    newPath: string,
    content: string
  ) => {
    setFormData((prev) => {
      const mounts = [...(prev.mounts || [])];
      const files = { ...mounts[mountIndex].files };
      if (oldPath !== newPath) {
        delete files[oldPath];
      }
      files[newPath] = content;
      mounts[mountIndex] = { ...mounts[mountIndex], files };
      return { ...prev, mounts };
    });
  };

  const removeMountFile = (mountIndex: number, path: string) => {
    setFormData((prev) => {
      const mounts = [...(prev.mounts || [])];
      const files = { ...mounts[mountIndex].files };
      delete files[path];
      mounts[mountIndex] = { ...mounts[mountIndex], files };
      return { ...prev, mounts };
    });
  };

  if (loading) return <div>Loading config profiles...</div>;

  return (
    <section className="stack">
      <div className="page-header">
        <div>
          <p className="eyebrow">Settings</p>
          <h1>Config Profiles</h1>
        </div>
        <button className="secondary-button" type="button" onClick={() => navigate("/settings")}>
          Back to settings
        </button>
      </div>

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

      {!showForm && (
        <button
          className="primary-button"
          type="button"
          onClick={() => {
            resetForm();
            setShowForm(true);
          }}
        >
          <Icon name="add" size="sm" />
          Create Profile
        </button>
      )}

      {showForm && (
        <form onSubmit={editingProfile ? handleUpdate : handleCreate} className="card stack">
          <h3>{editingProfile ? "Edit Profile" : "Create Profile"}</h3>

          <div className="form-group">
            <label htmlFor="profile-name">Name *</label>
            <input
              id="profile-name"
              type="text"
              value={formData.name}
              onChange={(e) => updateFormField("name", e.target.value)}
              placeholder="e.g., Development Environment"
              required
            />
          </div>

          <div className="form-group">
            <label htmlFor="profile-description">Description</label>
            <input
              id="profile-description"
              type="text"
              value={formData.description || ""}
              onChange={(e) => updateFormField("description", e.target.value || undefined)}
              placeholder="Optional description"
            />
          </div>

          <div className="form-group">
            <label htmlFor="profile-project">Project ID</label>
            <input
              id="profile-project"
              type="text"
              value={formData.project_id || ""}
              onChange={(e) => updateFormField("project_id", e.target.value || undefined)}
              placeholder="Optional project UUID"
            />
          </div>

          <div className="form-group">
            <label htmlFor="profile-tool">Tool Type ID</label>
            <input
              id="profile-tool"
              type="text"
              value={formData.tool_type_id || ""}
              onChange={(e) => updateFormField("tool_type_id", e.target.value || undefined)}
              placeholder="Optional tool type UUID"
            />
          </div>

          <div className="form-group">
            <label className="checkbox-label">
              <input
                type="checkbox"
                checked={formData.is_default || false}
                onChange={(e) => updateFormField("is_default", e.target.checked)}
              />
              Set as default for this scope
            </label>
          </div>

          <div className="form-section">
            <h4>Environment Variables</h4>
            {Object.entries(formData.env_vars || {}).map(([key, value]) => (
              <div key={key} className="form-row">
                <input
                  type="text"
                  value={key}
                  onChange={(e) => updateEnvVar(key, e.target.value, value)}
                  placeholder="VAR_NAME"
                />
                <input
                  type="text"
                  value={value}
                  onChange={(e) => updateEnvVar(key, key, e.target.value)}
                  placeholder="value"
                />
                <button type="button" className="danger-button" onClick={() => removeEnvVar(key)}>
                  <Icon name="delete" size="sm" />
                </button>
              </div>
            ))}
            <button type="button" className="secondary-button" onClick={addEnvVar}>
              <Icon name="add" size="sm" />
              Add Variable
            </button>
          </div>

          <div className="form-section">
            <h4>Runtime Hints</h4>
            <textarea
              value={JSON.stringify(formData.runtime_hints || {}, null, 2)}
              onChange={(e) => {
                try {
                  const parsed = JSON.parse(e.target.value);
                  updateFormField("runtime_hints", parsed);
                } catch {
                  // Invalid JSON, ignore
                }
              }}
              placeholder='{"start_command": "npm start"}'
              rows={4}
            />
          </div>

          <div className="form-section">
            <h4>Files</h4>
            {Object.entries(formData.files || {}).map(([path, content]) => (
              <div key={path} className="file-entry">
                <input
                  type="text"
                  value={path}
                  onChange={(e) => updateFile(path, e.target.value, content)}
                  placeholder="relative/path/to/file"
                />
                <textarea
                  value={content}
                  onChange={(e) => updateFile(path, path, e.target.value)}
                  placeholder="File content"
                  rows={3}
                />
                <button type="button" className="danger-button" onClick={() => removeFile(path)}>
                  <Icon name="delete" size="sm" />
                </button>
              </div>
            ))}
            <button type="button" className="secondary-button" onClick={addFile}>
              <Icon name="add" size="sm" />
              Add File
            </button>
          </div>

          <div className="form-section">
            <h4>Mounts</h4>
            {(formData.mounts || []).map((mount, index) => (
              <div key={index} className="mount-entry card">
                <div className="form-row">
                  <input
                    type="text"
                    value={mount.target}
                    onChange={(e) => updateMount(index, { target: e.target.value })}
                    placeholder="/target/path"
                  />
                  <select
                    value={mount.mode}
                    onChange={(e) =>
                      updateMount(index, { mode: e.target.value as "ro" | "rw" })
                    }
                  >
                    <option value="rw">Read/Write</option>
                    <option value="ro">Read-Only</option>
                  </select>
                  <button
                    type="button"
                    className="danger-button"
                    onClick={() => removeMount(index)}
                  >
                    <Icon name="delete" size="sm" />
                  </button>
                </div>

                <div className="mount-files">
                  {Object.entries(mount.files).map(([path, content]) => (
                    <div key={path} className="file-entry">
                      <input
                        type="text"
                        value={path}
                        onChange={(e) =>
                          updateMountFile(index, path, e.target.value, content)
                        }
                        placeholder="relative/path"
                      />
                      <textarea
                        value={content}
                        onChange={(e) =>
                          updateMountFile(index, path, path, e.target.value)
                        }
                        placeholder="File content"
                        rows={2}
                      />
                      <button
                        type="button"
                        className="danger-button"
                        onClick={() => removeMountFile(index, path)}
                      >
                        <Icon name="delete" size="sm" />
                      </button>
                    </div>
                  ))}
                  <button
                    type="button"
                    className="secondary-button"
                    onClick={() => addMountFile(index)}
                  >
                    <Icon name="add" size="sm" />
                    Add File
                  </button>
                </div>
              </div>
            ))}
            <button type="button" className="secondary-button" onClick={addMount}>
              <Icon name="add" size="sm" />
              Add Mount
            </button>
          </div>

          <div className="form-actions">
            <button type="submit" className="primary-button">
              <Icon name="save" size="sm" />
              {editingProfile ? "Update Profile" : "Create Profile"}
            </button>
            <button type="button" className="secondary-button" onClick={resetForm}>
              Cancel
            </button>
          </div>
        </form>
      )}

      {previewData && (
        <div className="card stack preview-panel">
          <h3>Resolved Profile Preview</h3>
          <pre>{JSON.stringify(previewData, null, 2)}</pre>
          <button className="secondary-button" onClick={() => setPreviewData(null)}>
            Close Preview
          </button>
        </div>
      )}

      <div className="profiles-list">
        {profiles.length === 0 ? (
          <p className="muted">No config profiles yet. Create one above.</p>
        ) : (
          profiles.map((profile) => (
            <div key={profile.id} className="profile-card card">
              <div className="profile-header">
                <div>
                  <h3>{profile.name}</h3>
                  {profile.description && <p className="muted">{profile.description}</p>}
                  <div className="profile-meta">
                    {profile.project_id && (
                      <span className="badge">Project: {profile.project_id}</span>
                    )}
                    {profile.tool_type_id && (
                      <span className="badge">Tool: {profile.tool_type_id}</span>
                    )}
                    {profile.is_default && <span className="badge badge-primary">Default</span>}
                  </div>
                </div>
                <div className="profile-actions">
                  <button
                    className="secondary-button"
                    onClick={() => handlePreview(profile.id)}
                    disabled={previewingId === profile.id}
                  >
                    {previewingId === profile.id ? (
                      <>
                        <Icon name="loading" size="sm" />
                        Previewing...
                      </>
                    ) : (
                      <>
                      <Icon name="info" size="sm" />
                      Preview
                      </>
                    )}
                  </button>
                  <button className="secondary-button" onClick={() => startEdit(profile)}>
                    <Icon name="edit" size="sm" />
                    Edit
                  </button>
                  <button
                    className="danger-button"
                    onClick={() => handleDelete(profile.id)}
                  >
                    <Icon name="delete" size="sm" />
                    Delete
                  </button>
                </div>
              </div>

              {profile.includes.length > 0 && (
                <div className="profile-includes">
                  <span className="muted">Includes: {profile.includes.length} profile(s)</span>
                </div>
              )}

              <div className="profile-summary">
                {Object.keys(profile.env_vars).length > 0 && (
                  <span>{Object.keys(profile.env_vars).length} env vars</span>
                )}
                {Object.keys(profile.files).length > 0 && (
                  <span>{Object.keys(profile.files).length} files</span>
                )}
                {profile.mounts.length > 0 && (
                  <span>{profile.mounts.length} mounts</span>
                )}
              </div>
            </div>
          ))
        )}
      </div>
    </section>
  );
};
