import { Icon } from "../../icon";
import { GitMountEditor } from "../git/git-mount-editor";
import type { ConfigProfile, CreateConfigProfileRequest, ResolvedProfile } from "../../../api/config-profiles";
import type { ProjectWithRepos } from "../../../types";
import type { ToolType } from "../../../api/tool-types";

interface Props {
  isCreating: boolean;
  selectedProfile: ConfigProfile | null;
  formData: CreateConfigProfileRequest;
  includedProfileIds: string[];
  dragOverIndex: number | null;
  error: string | null;
  saveStatus: "idle" | "saving" | "saved" | "error";
  previewData: ResolvedProfile | null;
  previewingId: string | null;
  projects: ProjectWithRepos[];
  toolTypes: ToolType[];
  availableProfiles: ConfigProfile[];
  getIncludedProfile: (id: string) => ConfigProfile | undefined;
  getScopeLabel: (profile: ConfigProfile) => string;
  onFormChange: <K extends keyof CreateConfigProfileRequest>(key: K, value: CreateConfigProfileRequest[K]) => void;
  onSubmit: (e?: React.FormEvent) => void;
  onReset: () => void;
  onPreview: () => void;
  onAddInclude: (id: string) => void;
  onRemoveInclude: (index: number) => void;
  onDragStart: (e: React.DragEvent, index: number) => void;
  onDragOver: (e: React.DragEvent, index: number) => void;
  onDragLeave: () => void;
  onDrop: (e: React.DragEvent, index: number) => void;
  onAddEnvVar: () => void;
  onUpdateEnvVar: (oldKey: string, newKey: string, value: string) => void;
  onRemoveEnvVar: (key: string) => void;
  onAddFile: () => void;
  onUpdateFile: (oldPath: string, newPath: string, content: string) => void;
  onRemoveFile: (path: string) => void;
  onAddMount: () => void;
  onUpdateMount: (index: number, updates: Partial<ConfigProfile["mounts"][0]>) => void;
  onRemoveMount: (index: number) => void;
  onAddMountFile: (mountIndex: number) => void;
  onUpdateMountFile: (mountIndex: number, oldPath: string, newPath: string, content: string) => void;
  onRemoveMountFile: (mountIndex: number, path: string) => void;
  onClosePreview: () => void;
}

export const ConfigProfileEditorPanel = ({
  isCreating,
  selectedProfile,
  formData,
  includedProfileIds,
  dragOverIndex,
  error,
  saveStatus,
  previewData,
  previewingId,
  projects,
  toolTypes,
  availableProfiles,
  getIncludedProfile,
  getScopeLabel,
  onFormChange,
  onSubmit,
  onReset,
  onPreview,
  onAddInclude,
  onRemoveInclude,
  onDragStart,
  onDragOver,
  onDragLeave,
  onDrop,
  onAddEnvVar,
  onUpdateEnvVar,
  onRemoveEnvVar,
  onAddFile,
  onUpdateFile,
  onRemoveFile,
  onAddMount,
  onUpdateMount,
  onRemoveMount,
  onAddMountFile,
  onUpdateMountFile,
  onRemoveMountFile,
  onClosePreview,
}: Props) => {
  const hasSelection = isCreating || selectedProfile;

  return (
    <div style={{ flex: 1, overflow: "auto", padding: "1.5rem", minWidth: 0 }}>
      {!hasSelection ? (
        <div style={{ textAlign: "center", paddingTop: "4rem", color: "var(--muted)" }}>
          <div style={{ opacity: 0.3, marginBottom: "1rem" }}>
            <Icon name="folder" size="lg" />
          </div>
          <h3 style={{ margin: "0 0 0.5rem 0", fontWeight: 500 }}>Select a config profile</h3>
          <p style={{ margin: 0 }}>Choose a profile from the list to edit, or create a new one.</p>
        </div>
      ) : (
        <div>
          <div style={{ marginBottom: "1.5rem", display: "flex", justifyContent: "space-between", alignItems: "flex-start" }}>
            <div>
              <h1 style={{ margin: "0 0 0.5rem 0", fontSize: "1.5rem" }}>
                {isCreating ? "Create Profile" : selectedProfile?.name}
              </h1>
              {!isCreating && selectedProfile && (
                <p className="muted" style={{ margin: 0 }}>
                  {selectedProfile.project_id &&
                    `Project: ${projects.find((p) => p.id === selectedProfile.project_id)?.name || selectedProfile.project_id}`}
                  {selectedProfile.project_id && selectedProfile.tool_type_id && " · "}
                  {selectedProfile.tool_type_id &&
                    `Tool: ${toolTypes.find((t) => t.id === selectedProfile.tool_type_id)?.display_name || selectedProfile.tool_type_id}`}
                </p>
              )}
            </div>
            {!isCreating && selectedProfile && (
              <div style={{ display: "flex", gap: "0.5rem" }}>
                <button className="secondary-button" onClick={onPreview} disabled={previewingId === selectedProfile.id}>
                  {previewingId === selectedProfile.id ? (
                    <><Icon name="loading" size="sm" /> Previewing...</>
                  ) : (
                    <><Icon name="info" size="sm" /> Preview</>
                  )}
                </button>
              </div>
            )}
          </div>

          {error && <div className="error" style={{ marginBottom: "1rem" }}>{error}</div>}

          {saveStatus === "saved" && (
            <div style={{ marginBottom: "1rem", padding: "0.75rem 1rem", background: "var(--success-bg, #dcfce7)", color: "var(--success, #166534)", borderRadius: "0.375rem", display: "flex", alignItems: "center", gap: "0.5rem" }}>
              <Icon name="success" size="sm" />
              Profile saved successfully
            </div>
          )}

          <form onSubmit={onSubmit} className="stack" style={{ gap: "1.25rem", maxWidth: "800px" }}>
            <div className="form-group">
              <label htmlFor="profile-name">Name *</label>
              <input id="profile-name" type="text" value={formData.name} onChange={(e) => onFormChange("name", e.target.value)} placeholder="e.g., Development Environment" className="form-input" required />
            </div>

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

            <div className="row" style={{ gap: "1rem" }}>
              <div className="form-group" style={{ flex: 1 }}>
                <label htmlFor="profile-project">Project</label>
                <select id="profile-project" value={formData.project_id || ""} onChange={(e) => onFormChange("project_id", e.target.value || undefined)} className="form-input">
                  <option value="">None (Global)</option>
                  {projects.map((project) => (
                    <option key={project.id} value={project.id}>{project.name}</option>
                  ))}
                </select>
              </div>
              <div className="form-group" style={{ flex: 1 }}>
                <label htmlFor="profile-tool">Tool Type</label>
                <select id="profile-tool" value={formData.tool_type_id || ""} onChange={(e) => onFormChange("tool_type_id", e.target.value || undefined)} className="form-input">
                  <option value="">None</option>
                  {toolTypes.map((toolType) => (
                    <option key={toolType.id} value={toolType.id}>{toolType.display_name}</option>
                  ))}
                </select>
              </div>
            </div>

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

            <div className="form-section">
              <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: "0.75rem" }}>
                <h4 style={{ margin: 0 }}>Includes</h4>
                <span className="muted" style={{ fontSize: "0.875rem" }}>{includedProfileIds.length} included</span>
              </div>
              {includedProfileIds.length === 0 ? (
                <p className="muted" style={{ fontSize: "0.875rem", margin: "0 0 0.75rem 0" }}>No profiles included. Add profiles to compose configurations.</p>
              ) : (
                <div style={{ marginBottom: "0.75rem" }}>
                  {includedProfileIds.map((profileId, index) => {
                    const profile = getIncludedProfile(profileId);
                    if (!profile) return null;
                    return (
                      <div
                        key={`${profileId}-${index}`}
                        draggable
                        onDragStart={(e) => onDragStart(e, index)}
                        onDragOver={(e) => onDragOver(e, index)}
                        onDragLeave={onDragLeave}
                        onDrop={(e) => onDrop(e, index)}
                        style={{ display: "flex", alignItems: "center", gap: "0.5rem", padding: "0.5rem 0.75rem", background: dragOverIndex === index ? "var(--brand-bg, #e0e7ff)" : "var(--panel)", border: "1px solid var(--border)", borderRadius: "0.375rem", marginBottom: "0.25rem", cursor: "grab", transition: "background 0.15s" }}
                      >
                        <span style={{ cursor: "grab", color: "var(--muted)" }}><Icon name="drag" size="sm" /></span>
                        <span style={{ flex: 1, fontWeight: 500 }}>{profile.name}</span>
                        <span style={{ fontSize: "0.75rem", padding: "0.125rem 0.375rem", background: "var(--badge-bg, #f3f4f6)", color: "var(--muted)", borderRadius: "0.25rem", textTransform: "uppercase", letterSpacing: "0.025em" }}>{getScopeLabel(profile)}</span>
                        <button type="button" onClick={() => onRemoveInclude(index)} style={{ background: "none", border: "none", color: "var(--danger)", cursor: "pointer", padding: "0.25rem", borderRadius: "0.25rem" }} title="Remove include"><Icon name="delete" size="sm" /></button>
                      </div>
                    );
                  })}
                </div>
              )}
              {availableProfiles.length > 0 && (
                <div className="form-group" style={{ marginBottom: 0 }}>
                  <select value="" onChange={(e) => { if (e.target.value) { onAddInclude(e.target.value); e.target.value = ""; } }} className="form-input">
                    <option value="">+ Add Include...</option>
                    {availableProfiles.map((p) => (
                      <option key={p.id} value={p.id}>{p.name} ({getScopeLabel(p)})</option>
                    ))}
                  </select>
                </div>
              )}
            </div>

            <div className="form-section">
              <h4 style={{ margin: "0 0 0.75rem 0" }}>Environment Variables</h4>
              {Object.entries(formData.env_vars || {}).map(([key, value], idx) => (
                <div key={idx} className="form-row" style={{ gap: "0.5rem", marginBottom: "0.5rem" }}>
                  <input type="text" value={key} onChange={(e) => onUpdateEnvVar(key, e.target.value, value)} placeholder="VAR_NAME" className="form-input" style={{ flex: 1 }} />
                  <input type="text" value={value} onChange={(e) => onUpdateEnvVar(key, key, e.target.value)} placeholder="value" className="form-input" style={{ flex: 1 }} />
                  <button type="button" className="ghost-button small" onClick={() => onRemoveEnvVar(key)}><Icon name="delete" size="sm" /></button>
                </div>
              ))}
              <button type="button" className="secondary-button" onClick={onAddEnvVar}><Icon name="add" size="sm" /> Add Variable</button>
            </div>

            <div className="form-section">
              <h4 style={{ margin: "0 0 0.75rem 0" }}>Runtime Hints</h4>
              <textarea value={JSON.stringify(formData.runtime_hints || {}, null, 2)} onChange={(e) => { try { const parsed = JSON.parse(e.target.value); onFormChange("runtime_hints", parsed); } catch { /* ignore */ } }} placeholder='{"start_command": "npm start"}' rows={4} className="form-input" style={{ fontFamily: "monospace", fontSize: "0.875rem" }} />
            </div>

            <div className="form-section">
              <h4 style={{ margin: "0 0 0.5rem 0" }}>Files</h4>
              <p className="muted" style={{ margin: "0 0 0.75rem 0", fontSize: "0.875rem" }}>Relative paths written to the instance directory. Use Mounts below for absolute container paths.</p>
              {Object.entries(formData.files || {}).map(([path, content], idx) => (
                <div key={idx} className="card" style={{ padding: "0.75rem", marginBottom: "0.5rem" }}>
                  <div style={{ display: "flex", gap: "0.5rem", marginBottom: "0.5rem" }}>
                    <input type="text" value={path} onChange={(e) => onUpdateFile(path, e.target.value, content)} placeholder="relative/path/to/file" className="form-input" style={{ flex: 1 }} />
                    <button type="button" className="ghost-button small" onClick={() => onRemoveFile(path)}><Icon name="delete" size="sm" /></button>
                  </div>
                  <textarea value={content} onChange={(e) => onUpdateFile(path, path, e.target.value)} placeholder="File content" rows={3} className="form-input" style={{ fontFamily: "monospace", fontSize: "0.875rem" }} />
                </div>
              ))}
              <button type="button" className="secondary-button" onClick={onAddFile}><Icon name="add" size="sm" /> Add File</button>
            </div>

            <div className="form-section">
              <h4 style={{ margin: "0 0 0.5rem 0" }}>Mounts</h4>
              <p className="muted" style={{ margin: "0 0 0.75rem 0", fontSize: "0.875rem" }}>Bind directories into the container at absolute paths. Files are relative to the mount target.</p>
              {(formData.mounts || []).map((mount, index) => (
                <div key={index} className="card" style={{ padding: "1rem", marginBottom: "0.75rem" }}>
                  <div className="form-row" style={{ gap: "0.5rem", marginBottom: "0.75rem" }}>
                    <input type="text" value={mount.target} onChange={(e) => onUpdateMount(index, { target: e.target.value })} placeholder="/target/path" className="form-input" style={{ flex: 1 }} />
                    <select value={mount.mode} onChange={(e) => onUpdateMount(index, { mode: e.target.value as "ro" | "rw" })} className="form-input" style={{ width: "120px" }}>
                      <option value="rw">Read/Write</option>
                      <option value="ro">Read-Only</option>
                    </select>
                    <button type="button" className="ghost-button small" onClick={() => onRemoveMount(index)}><Icon name="delete" size="sm" /></button>
                  </div>
                  <div style={{ marginLeft: "1rem" }}>
                    {Object.entries(mount.files).map(([path, content], idx) => (
                      <div key={idx} style={{ display: "flex", gap: "0.5rem", marginBottom: "0.5rem" }}>
                        <input type="text" value={path} onChange={(e) => onUpdateMountFile(index, path, e.target.value, content)} placeholder="relative/path" className="form-input" style={{ flex: 1 }} />
                        <textarea value={content} onChange={(e) => onUpdateMountFile(index, path, path, e.target.value)} placeholder="File content" rows={2} className="form-input" style={{ flex: 2, fontFamily: "monospace", fontSize: "0.875rem" }} />
                        <button type="button" className="ghost-button small" onClick={() => onRemoveMountFile(index, path)}><Icon name="delete" size="sm" /></button>
                      </div>
                    ))}
                    <button type="button" className="secondary-button small" onClick={() => onAddMountFile(index)} style={{ fontSize: "0.875rem" }}><Icon name="add" size="sm" /> Add File to Mount</button>
                  </div>
                </div>
              ))}
              <button type="button" className="secondary-button" onClick={onAddMount}><Icon name="add" size="sm" /> Add Mount</button>
            </div>

            <div className="form-section">
              <GitMountEditor mounts={formData.git_mounts || []} onChange={(git_mounts) => onFormChange("git_mounts", git_mounts)} />
            </div>

            <div className="dialog-actions" style={{ marginTop: "1rem", position: "sticky", bottom: "1rem", background: "var(--surface)", padding: "1rem", borderRadius: "0.5rem", border: "1px solid var(--border)" }}>
              <button type="submit" disabled={saveStatus === "saving"}>
                <Icon name={isCreating ? "add" : "save"} size="sm" />
                {saveStatus === "saving" ? "Saving..." : isCreating ? "Create Profile" : "Save Changes"}
              </button>
              {(isCreating || saveStatus !== "idle") && (
                <button type="button" onClick={onReset} className="button-secondary"><Icon name="cancel" size="sm" /> Discard</button>
              )}
            </div>
          </form>

          {previewData && (
            <div className="card stack" style={{ marginTop: "2rem", padding: "1rem" }}>
              <h3>Resolved Profile Preview</h3>
              <pre style={{ overflow: "auto", maxHeight: "400px", fontSize: "0.8125rem" }}>{JSON.stringify(previewData, null, 2)}</pre>
              <button className="secondary-button" onClick={onClosePreview}>Close Preview</button>
            </div>
          )}
        </div>
      )}
    </div>
  );
};
