import { useState, useEffect } from "react";
import { Icon } from "./icon";
import { createInstance, startInstance, type ToolInstance } from "../api/sessions";
import type { Project } from "../types";
import { listRepositoryBranches, type GitRepository, type Branch } from "../api/git_repositories";
import type { ToolType } from "../api/tool_types";
import { listSSHKeys, type SSHKey } from "../api/ssh_keys";
import { listConfigProfiles, type ConfigProfile } from "../api/config_profiles";

interface CreateSessionFormProps {
  projects: Project[];
  repositories: GitRepository[];
  toolTypes: ToolType[];
  fixedProjectId?: string;
  fixedRepoId?: string;
  projectName?: string;
  repoName?: string;
  showCloneMode?: boolean;
  showFixedFields?: boolean;
  onProjectChange?: (projectId: string) => void;
  onSuccess?: (instance: ToolInstance) => void;
  onCancel?: () => void;
  submitLabel?: string;
  className?: string;
}

export const CreateSessionForm = ({
  projects,
  repositories,
  toolTypes,
  fixedProjectId,
  fixedRepoId,
  projectName,
  repoName,
  showCloneMode = true,
  showFixedFields = true,
  onProjectChange,
  onSuccess,
  onCancel,
  submitLabel = "Create Session",
  className = "",
}: CreateSessionFormProps) => {
  const [selectedProject, setSelectedProject] = useState(fixedProjectId || "");
  const [selectedRepo, setSelectedRepo] = useState(fixedRepoId || "");
  const [selectedToolType, setSelectedToolType] = useState("");
  const [displayName, setDisplayName] = useState("");
  const [cloneMode, setCloneMode] = useState<"mount" | "clone">("mount");
  const [branch, setBranch] = useState("main");
  const [sshKeys, setSshKeys] = useState<SSHKey[]>([]);
  const [configProfiles, setConfigProfiles] = useState<ConfigProfile[]>([]);
  const [selectedConfigProfile, setSelectedConfigProfile] = useState("");
  const [selectedSshKeyIds, setSelectedSshKeyIds] = useState<string[]>([]);
  
  const [branches, setBranches] = useState<Branch[]>([]);
  const [isLoadingBranches, setIsLoadingBranches] = useState(false);
  const [isCreatingNewBranch, setIsCreatingNewBranch] = useState(false);
  const [newBranchName, setNewBranchName] = useState("");
  const [baseBranch, setBaseBranch] = useState("");
  
  const [status, setStatus] = useState<"idle" | "creating" | "error">("idle");
  const [progress, setProgress] = useState("");
  const [error, setError] = useState<string | null>(null);

  // Load SSH keys
  useEffect(() => {
    const loadKeys = async () => {
      try {
        const keys = await listSSHKeys();
        setSshKeys(keys);
      } catch {
        // ignore
      }
    };
    void loadKeys();
  }, []);

  // Load config profiles when tool type is selected
  useEffect(() => {
    const projectId = fixedProjectId || selectedProject;
    if (!selectedToolType || !projectId) {
      setConfigProfiles([]);
      setSelectedConfigProfile("");
      return;
    }
    const loadProfiles = async () => {
      try {
        const profiles = await listConfigProfiles(projectId, selectedToolType);
        setConfigProfiles(profiles);
        // Auto-select default if available
        const defaultProfile = profiles.find((p) => p.is_default);
        if (defaultProfile) {
          setSelectedConfigProfile(defaultProfile.id);
        }
      } catch {
        // ignore
      }
    };
    void loadProfiles();
  }, [selectedToolType, selectedProject, fixedProjectId]);

  // Load branches when selected repo changes
  useEffect(() => {
    const projectId = fixedProjectId || selectedProject;
    if (!selectedRepo || !projectId || !showCloneMode) {
      setBranches([]);
      return;
    }
    const loadBranches = async () => {
      setIsLoadingBranches(true);
      try {
        const response = await listRepositoryBranches(projectId, selectedRepo);
        setBranches(response.branches);
        if (response.default_branch) {
          setBranch(response.default_branch);
          setBaseBranch(response.default_branch);
        }
      } catch {
        // ignore
      } finally {
        setIsLoadingBranches(false);
      }
    };
    void loadBranches();
  }, [selectedRepo, selectedProject, fixedProjectId, showCloneMode]);

  // Filter repositories by selected project
  const availableRepos = selectedProject
    ? repositories.filter((r) => r.project_id === selectedProject)
    : [];

  const handleSubmit = async (event: React.FormEvent) => {
    event.preventDefault();
    setError(null);

    const projectId = fixedProjectId || selectedProject;
    const repoId = fixedRepoId || selectedRepo;

    if (!projectId || !repoId || !selectedToolType) {
      setError("Project, repository, and tool type are required");
      return;
    }

    if (showCloneMode && cloneMode === "clone") {
      const repo = repositories.find((r) => r.id === repoId);
      if (!repo?.ssh_key_id) {
        setError("Repository must have an SSH key assigned for clone mode");
        return;
      }
    }

    setStatus("creating");
    setProgress("Creating instance...");

    try {
      const instance = await createInstance(
        projectId,
        repoId,
        selectedToolType,
        displayName || undefined,
        showCloneMode ? cloneMode : undefined,
        showCloneMode && cloneMode === "clone"
          ? isCreatingNewBranch
            ? baseBranch
            : branch
          : undefined,
        showCloneMode && cloneMode === "clone" && isCreatingNewBranch
          ? newBranchName
          : undefined,
        selectedConfigProfile || undefined,
        selectedSshKeyIds.length > 0 ? selectedSshKeyIds : undefined
      );

      setProgress("Starting container...");
      await startInstance(
        projectId,
        repoId,
        instance.id,
        selectedConfigProfile || undefined,
        selectedSshKeyIds.length > 0 ? selectedSshKeyIds : undefined
      );

      // Reset form
      if (!fixedProjectId) setSelectedProject("");
      if (!fixedRepoId) setSelectedRepo("");
      setSelectedToolType("");
      setDisplayName("");
      setCloneMode("mount");
      setBranch("main");
      setIsCreatingNewBranch(false);
      setNewBranchName("");
      setBaseBranch("");
        setBranches([]);
      setSelectedSshKeyIds([]);
      setStatus("idle");
      
      onSuccess?.(instance);
    } catch {
      setStatus("error");
      setError("Failed to create session");
      setProgress("");
    }
  };

  const isSubmitting = status === "creating";

  // Determine which steps are active/unlocked
  const hasProject = !!(fixedProjectId || selectedProject);
  const hasRepo = !!(fixedRepoId || selectedRepo);
  const hasToolType = !!selectedToolType;

  const renderStep = (
    label: string,
    number: number,
    isActive: boolean,
    isComplete: boolean,
    children: React.ReactNode
  ) => {
    const stepClass = `workflow-step ${isActive ? "active" : ""} ${isComplete ? "complete" : ""}`;
    return (
      <div className={stepClass}>
        <div className="workflow-step-header">
          <span className="workflow-step-number">{number}</span>
          <span className="workflow-step-label">{label}</span>
        </div>
        <div className="workflow-step-content">
          {children}
        </div>
      </div>
    );
  };

  return (
    <div className={`create-session-form-wrapper ${className}`}>
      {isSubmitting && (
        <div className="loading-overlay">
          <div className="loading-content">
            <Icon name="loading" size="lg" />
            <p>{progress || "Creating session..."}</p>
          </div>
        </div>
      )}

      <form onSubmit={handleSubmit} className="stack create-session-form workflow-form">
        {/* Step 1: Project */}
        {renderStep("Select Project", 1, true, hasProject,
          fixedProjectId && showFixedFields ? (
            <label className="form-field">
              <input
                type="text"
                value={projectName || projects.find((p) => p.id === fixedProjectId)?.name || ""}
                disabled
                readOnly
              />
            </label>
          ) : (
            <label className="form-field">
              <select
                value={selectedProject}
                onChange={(e) => {
                  const value = e.target.value;
                  setSelectedProject(value);
                  setSelectedRepo("");
                  setSelectedToolType("");
                  setCloneMode("mount");
                  setIsCreatingNewBranch(false);
                  onProjectChange?.(value);
                }}
                disabled={isSubmitting}
              >
                <option value="">Select project...</option>
                {projects.map((p) => (
                  <option key={p.id} value={p.id}>
                    {p.name}
                  </option>
                ))}
              </select>
            </label>
          )
        )}

        {/* Step 2: Repository */}
        {hasProject && renderStep("Select Repository", 2, true, hasRepo,
          fixedRepoId && showFixedFields ? (
            <label className="form-field">
              <input
                type="text"
                value={repoName || repositories.find((r) => r.id === fixedRepoId)?.name || ""}
                disabled
                readOnly
              />
            </label>
          ) : (
            <label className="form-field">
              <select
                value={selectedRepo}
                onChange={(e) => {
                  setSelectedRepo(e.target.value);
                  setSelectedToolType("");
                  setCloneMode("mount");
                  setIsCreatingNewBranch(false);
                }}
                disabled={!hasProject || isSubmitting}
              >
                <option value="">Select repository...</option>
                {availableRepos.map((r) => (
                  <option key={r.id} value={r.id}>
                    {r.name}
                  </option>
                ))}
              </select>
            </label>
          )
        )}

        {/* Step 3: Tool Type */}
        {hasRepo && renderStep("Select Tool", 3, true, hasToolType,
          <label className="form-field">
            <select
              value={selectedToolType}
              onChange={(e) => {
                setSelectedToolType(e.target.value);
                setCloneMode("mount");
                setIsCreatingNewBranch(false);
              }}
              disabled={!hasRepo || isSubmitting}
            >
              <option value="">Select tool...</option>
              {toolTypes.map((t) => (
                <option key={t.id} value={t.id}>
                  {t.display_name}
                </option>
              ))}
            </select>
          </label>
        )}

        {/* Step 4: Config Profile */}
        {hasToolType && renderStep("Config Profile (optional)", 4, true, false,
          <label className="form-field">
            <select
              value={selectedConfigProfile}
              onChange={(e) => setSelectedConfigProfile(e.target.value)}
              disabled={!hasToolType || isSubmitting}
            >
              <option value="">No profile (use tool defaults)</option>
              {configProfiles.map((p) => (
                <option key={p.id} value={p.id}>
                  {p.name} {p.is_default ? "(default)" : ""}
                </option>
              ))}
            </select>
          </label>
        )}

        {/* Step 5: SSH Keys */}
        {hasToolType && renderStep("SSH Keys (optional)", 5, true, false,
          <div className="form-field">
            <div style={{ display: "flex", flexWrap: "wrap", gap: "0.5rem" }}>
              {sshKeys.length === 0 && (
                <span className="muted">No SSH keys configured.</span>
              )}
              {sshKeys.map((key) => (
                <label
                  key={key.id}
                  className="checkbox-label"
                  style={{
                    display: "flex",
                    alignItems: "center",
                    gap: "0.25rem",
                    padding: "0.375rem 0.75rem",
                    background: "var(--panel)",
                    borderRadius: "0.375rem",
                    border: "1px solid var(--border)",
                    cursor: "pointer",
                  }}
                >
                  <input
                    type="checkbox"
                    checked={selectedSshKeyIds.includes(key.id)}
                    onChange={(e) => {
                      if (e.target.checked) {
                        setSelectedSshKeyIds((prev) => [...prev, key.id]);
                      } else {
                        setSelectedSshKeyIds((prev) =>
                          prev.filter((id) => id !== key.id)
                        );
                      }
                    }}
                    disabled={isSubmitting}
                  />
                  {key.name}
                </label>
              ))}
            </div>
            <div className="hint" style={{ marginTop: "0.5rem" }}>
              Selected keys will be mounted into the container at ~/.ssh
            </div>
          </div>
        )}

        {/* Step 6: Clone Mode & Branch */}
        {showCloneMode && hasToolType && renderStep("Repository Access", 6, true, false,
          <div className="form-row">
            <label className="form-field">
              <div className="radio-group">
                <label className="radio-label">
                  <input
                    type="radio"
                    name="cloneMode"
                    value="mount"
                    checked={cloneMode === "mount"}
                    onChange={(e) => {
                      setCloneMode(e.target.value as "mount" | "clone");
                      setIsCreatingNewBranch(false);
                    }}
                    disabled={isSubmitting}
                  />
                  Mount (live sync)
                </label>
                <label className="radio-label">
                  <input
                    type="radio"
                    name="cloneMode"
                    value="clone"
                    checked={cloneMode === "clone"}
                    onChange={(e) => {
                      setCloneMode(e.target.value as "mount" | "clone");
                      setIsCreatingNewBranch(false);
                    }}
                    disabled={isSubmitting}
                  />
                  Clone fresh copy
                </label>
              </div>
            </label>

            {cloneMode === "clone" && (
              <>
                <label className="form-field">
                  Branch
                  {isLoadingBranches ? (
                    <span className="muted">Loading branches...</span>
                  ) : (
                    <select
                      value={isCreatingNewBranch ? "__new__" : branch}
                      onChange={(e) => {
                        const value = e.target.value;
                        if (value === "__new__") {
                          setIsCreatingNewBranch(true);
                          setNewBranchName("");
                        } else {
                          setIsCreatingNewBranch(false);
                          setBranch(value);
                          setBaseBranch(value);
                        }
                      }}
                      disabled={isSubmitting}
                    >
                      {branches.map((b) => (
                        <option key={b.name} value={b.name}>
                          {b.name} {b.is_default ? "(default)" : ""}
                        </option>
                      ))}
                      <option value="__new__">Create new branch...</option>
                    </select>
                  )}
                </label>

                {isCreatingNewBranch && (
                  <>
                    <label className="form-field">
                      New Branch Name
                      <input
                        type="text"
                        value={newBranchName}
                        onChange={(e) => setNewBranchName(e.target.value)}
                        placeholder="feature/my-new-branch"
                        required
                        disabled={isSubmitting}
                      />
                    </label>
                    <label className="form-field">
                      Base Branch
                      <select
                        value={baseBranch}
                        onChange={(e) => setBaseBranch(e.target.value)}
                        disabled={isSubmitting}
                      >
                        {branches.map((b) => (
                          <option key={b.name} value={b.name}>
                            {b.name} {b.is_default ? "(default)" : ""}
                          </option>
                        ))}
                      </select>
                    </label>
                  </>
                )}

                {selectedRepo && (
                  <div className="form-field ssh-key-info">
                    {(() => {
                      const repo = repositories.find((r) => r.id === selectedRepo);
                      if (!repo) return null;
                      if (repo.ssh_key_id) {
                        const key = sshKeys.find((k) => k.id === repo.ssh_key_id);
                        return (
                          <span className="success-text">
                            SSH key: {key?.name || "Assigned"}
                          </span>
                        );
                      }
                      return (
                        <span className="warning-text">
                          No SSH key assigned to this repository. Clone mode requires an SSH key.
                        </span>
                      );
                    })()}
                  </div>
                )}
              </>
            )}
          </div>
        )}

        {/* Step 7: Display Name */}
        {hasToolType && renderStep("Display Name (optional)", 7, true, !!displayName,
          <label className="form-field">
            <input
              type="text"
              value={displayName}
              onChange={(e) => setDisplayName(e.target.value)}
              placeholder="My Development Environment"
              disabled={isSubmitting}
            />
          </label>
        )}

        {/* Error & Submit */}
        {error && <p className="error-text">{error}</p>}

        {hasToolType && (
          <div className="form-actions">
            {onCancel && (
              <button
                className="secondary-button"
                type="button"
                onClick={onCancel}
                disabled={isSubmitting}
              >
                Cancel
              </button>
            )}
            <button
              className="primary-button"
              type="submit"
              disabled={isSubmitting}
            >
              {isSubmitting ? (
                <>
                  <Icon name="loading" size="sm" />
                  Creating...
                </>
              ) : (
                <>
                  <Icon name="add" size="sm" />
                  {submitLabel}
                </>
              )}
            </button>
          </div>
        )}
      </form>
    </div>
  );
};
