import { useEffect, useState, type FormEvent } from "react";
import { get, post, put, del } from "../api/client";
import { useAuth } from "../hooks/useAuth";
import type { Schema, SchemaSegment } from "../api/types";

interface EnumEditState {
  schemaName: string;
  segmentName: string;
  code: string;
  description: string;
  mode: "add" | "edit" | "delete";
}

export function SchemasPage() {
  const { user } = useAuth();
  const isEditor = user?.role === "admin" || user?.role === "editor";

  const [schemas, setSchemas] = useState<Schema[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [expanded, setExpanded] = useState<Set<string>>(new Set());
  const [editState, setEditState] = useState<EnumEditState | null>(null);
  const [formError, setFormError] = useState("");
  const [submitting, setSubmitting] = useState(false);

  const loadSchemas = async () => {
    try {
      const list = await get<Schema[]>("/api/schemas");
      setSchemas(list.filter((s) => s.name));
      setError(null);
    } catch (e) {
      setError(e instanceof Error ? e.message : "Failed to load schemas");
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    loadSchemas();
  }, []);

  const toggleExpand = (key: string) => {
    setExpanded((prev) => {
      const next = new Set(prev);
      if (next.has(key)) next.delete(key);
      else next.add(key);
      return next;
    });
  };

  const startAdd = (schemaName: string, segmentName: string) => {
    setEditState({
      schemaName,
      segmentName,
      code: "",
      description: "",
      mode: "add",
    });
    setFormError("");
  };

  const startEdit = (
    schemaName: string,
    segmentName: string,
    code: string,
    description: string,
  ) => {
    setEditState({ schemaName, segmentName, code, description, mode: "edit" });
    setFormError("");
  };

  const startDelete = (
    schemaName: string,
    segmentName: string,
    code: string,
  ) => {
    setEditState({
      schemaName,
      segmentName,
      code,
      description: "",
      mode: "delete",
    });
    setFormError("");
  };

  const cancelEdit = () => {
    setEditState(null);
    setFormError("");
  };

  const handleAddValue = async (e: FormEvent) => {
    e.preventDefault();
    if (!editState) return;
    setFormError("");
    setSubmitting(true);
    try {
      await post(
        `/api/schemas/${editState.schemaName}/segments/${editState.segmentName}/values`,
        { code: editState.code, description: editState.description },
      );
      cancelEdit();
      await loadSchemas();
    } catch (e) {
      setFormError(e instanceof Error ? e.message : "Failed to add value");
    } finally {
      setSubmitting(false);
    }
  };

  const handleUpdateValue = async (e: FormEvent) => {
    e.preventDefault();
    if (!editState) return;
    setFormError("");
    setSubmitting(true);
    try {
      await put(
        `/api/schemas/${editState.schemaName}/segments/${editState.segmentName}/values/${editState.code}`,
        { description: editState.description },
      );
      cancelEdit();
      await loadSchemas();
    } catch (e) {
      setFormError(e instanceof Error ? e.message : "Failed to update value");
    } finally {
      setSubmitting(false);
    }
  };

  const handleDeleteValue = async () => {
    if (!editState) return;
    setSubmitting(true);
    try {
      await del(
        `/api/schemas/${editState.schemaName}/segments/${editState.segmentName}/values/${editState.code}`,
      );
      cancelEdit();
      await loadSchemas();
    } catch (e) {
      setFormError(e instanceof Error ? e.message : "Failed to delete value");
    } finally {
      setSubmitting(false);
    }
  };

  if (loading)
    return <p style={{ color: "var(--ctp-subtext0)" }}>Loading schemas...</p>;
  if (error) return <p style={{ color: "var(--ctp-red)" }}>Error: {error}</p>;

  return (
    <div>
      <h2 style={{ marginBottom: "1rem" }}>
        Part Numbering Schemas ({schemas.length})
      </h2>

      {schemas.length === 0 ? (
        <div style={emptyStyle}>No schemas found.</div>
      ) : (
        schemas.map((schema) => (
          <SchemaCard
            key={schema.name}
            schema={schema}
            expanded={expanded}
            toggleExpand={toggleExpand}
            isEditor={isEditor}
            editState={editState}
            formError={formError}
            submitting={submitting}
            onStartAdd={startAdd}
            onStartEdit={startEdit}
            onStartDelete={startDelete}
            onCancelEdit={cancelEdit}
            onAdd={handleAddValue}
            onUpdate={handleUpdateValue}
            onDelete={handleDeleteValue}
            onEditStateChange={setEditState}
          />
        ))
      )}
    </div>
  );
}

// --- Sub-components (local to this file) ---

interface SchemaCardProps {
  schema: Schema;
  expanded: Set<string>;
  toggleExpand: (key: string) => void;
  isEditor: boolean;
  editState: EnumEditState | null;
  formError: string;
  submitting: boolean;
  onStartAdd: (schemaName: string, segmentName: string) => void;
  onStartEdit: (
    schemaName: string,
    segmentName: string,
    code: string,
    desc: string,
  ) => void;
  onStartDelete: (
    schemaName: string,
    segmentName: string,
    code: string,
  ) => void;
  onCancelEdit: () => void;
  onAdd: (e: FormEvent) => void;
  onUpdate: (e: FormEvent) => void;
  onDelete: () => void;
  onEditStateChange: (state: EnumEditState | null) => void;
}

function SchemaCard({
  schema,
  expanded,
  toggleExpand,
  isEditor,
  editState,
  formError,
  submitting,
  onStartAdd,
  onStartEdit,
  onStartDelete,
  onCancelEdit,
  onAdd,
  onUpdate,
  onDelete,
  onEditStateChange,
}: SchemaCardProps) {
  const segKey = `seg-${schema.name}`;
  const isExpanded = expanded.has(segKey);

  return (
    <div style={cardStyle}>
      <h3 style={{ color: "var(--ctp-mauve)", marginBottom: "0.5rem" }}>
        {schema.name}
      </h3>
      {schema.description && (
        <p style={{ color: "var(--ctp-subtext0)", marginBottom: "1rem" }}>
          {schema.description}
        </p>
      )}
      <p style={{ marginBottom: "0.5rem" }}>
        <strong>Format:</strong> <code style={codeStyle}>{schema.format}</code>
      </p>
      <p style={{ marginBottom: "1rem" }}>
        <strong>Version:</strong> {schema.version}
      </p>

      {schema.examples && schema.examples.length > 0 && (
        <>
          <p style={{ marginBottom: "0.5rem" }}>
            <strong>Examples:</strong>
          </p>
          <div
            style={{
              display: "flex",
              gap: "0.5rem",
              flexWrap: "wrap",
              marginBottom: "1rem",
            }}
          >
            {schema.examples.map((ex) => (
              <span
                key={ex}
                style={{
                  ...codeStyle,
                  fontFamily: "'JetBrains Mono', monospace",
                }}
              >
                {ex}
              </span>
            ))}
          </div>
        </>
      )}

      <div
        onClick={() => toggleExpand(segKey)}
        style={{
          cursor: "pointer",
          color: "var(--ctp-sapphire)",
          userSelect: "none",
          marginTop: "1rem",
        }}
      >
        {isExpanded ? "\u25BC" : "\u25B6"} View Segments (
        {schema.segments.length})
      </div>

      {isExpanded &&
        schema.segments.map((seg) => (
          <SegmentBlock
            key={seg.name}
            schemaName={schema.name}
            segment={seg}
            isEditor={isEditor}
            editState={editState}
            formError={formError}
            submitting={submitting}
            onStartAdd={onStartAdd}
            onStartEdit={onStartEdit}
            onStartDelete={onStartDelete}
            onCancelEdit={onCancelEdit}
            onAdd={onAdd}
            onUpdate={onUpdate}
            onDelete={onDelete}
            onEditStateChange={onEditStateChange}
          />
        ))}
    </div>
  );
}

interface SegmentBlockProps {
  schemaName: string;
  segment: SchemaSegment;
  isEditor: boolean;
  editState: EnumEditState | null;
  formError: string;
  submitting: boolean;
  onStartAdd: (schemaName: string, segmentName: string) => void;
  onStartEdit: (
    schemaName: string,
    segmentName: string,
    code: string,
    desc: string,
  ) => void;
  onStartDelete: (
    schemaName: string,
    segmentName: string,
    code: string,
  ) => void;
  onCancelEdit: () => void;
  onAdd: (e: FormEvent) => void;
  onUpdate: (e: FormEvent) => void;
  onDelete: () => void;
  onEditStateChange: (state: EnumEditState | null) => void;
}

function SegmentBlock({
  schemaName,
  segment,
  isEditor,
  editState,
  formError,
  submitting,
  onStartAdd,
  onStartEdit,
  onStartDelete,
  onCancelEdit,
  onAdd,
  onUpdate,
  onDelete,
  onEditStateChange,
}: SegmentBlockProps) {
  const isThisSegment = (es: EnumEditState | null) =>
    es !== null &&
    es.schemaName === schemaName &&
    es.segmentName === segment.name;

  const entries = segment.values
    ? Object.entries(segment.values).sort((a, b) => a[0].localeCompare(b[0]))
    : [];

  return (
    <div style={segmentStyle}>
      <div
        style={{
          display: "flex",
          justifyContent: "space-between",
          alignItems: "center",
          marginBottom: "0.5rem",
        }}
      >
        <h4 style={{ margin: 0, color: "var(--ctp-blue)" }}>{segment.name}</h4>
        <span style={typeBadgeStyle}>{segment.type}</span>
      </div>
      {segment.description && (
        <p
          style={{
            color: "var(--ctp-subtext0)",
            marginBottom: "0.5rem",
            fontSize: "0.85rem",
          }}
        >
          {segment.description}
        </p>
      )}

      {segment.type === "enum" && entries.length > 0 && (
        <div style={{ marginTop: "0.5rem", overflowX: "auto" }}>
          <table style={{ width: "100%", borderCollapse: "collapse" }}>
            <thead>
              <tr>
                <th style={thStyle}>Code</th>
                <th style={thStyle}>Description</th>
                {isEditor && (
                  <th style={{ ...thStyle, width: 120 }}>Actions</th>
                )}
              </tr>
            </thead>
            <tbody>
              {entries.map(([code, desc]) => {
                const isEditingThis =
                  isThisSegment(editState) &&
                  editState!.code === code &&
                  editState!.mode === "edit";
                const isDeletingThis =
                  isThisSegment(editState) &&
                  editState!.code === code &&
                  editState!.mode === "delete";

                if (isEditingThis) {
                  return (
                    <tr key={code}>
                      <td style={tdStyle}>
                        <code style={{ fontSize: "0.85rem" }}>{code}</code>
                      </td>
                      <td style={tdStyle}>
                        <form
                          onSubmit={onUpdate}
                          style={{
                            display: "flex",
                            gap: "0.5rem",
                            alignItems: "center",
                          }}
                        >
                          <input
                            type="text"
                            value={editState!.description}
                            onChange={(e) =>
                              onEditStateChange({
                                ...editState!,
                                description: e.target.value,
                              })
                            }
                            required
                            style={inlineInputStyle}
                            autoFocus
                          />
                          <button
                            type="submit"
                            disabled={submitting}
                            style={btnTinyPrimaryStyle}
                          >
                            Save
                          </button>
                          <button
                            type="button"
                            onClick={onCancelEdit}
                            style={btnTinyStyle}
                          >
                            Cancel
                          </button>
                        </form>
                        {formError && (
                          <div
                            style={{
                              color: "var(--ctp-red)",
                              fontSize: "0.75rem",
                              marginTop: "0.25rem",
                            }}
                          >
                            {formError}
                          </div>
                        )}
                      </td>
                      {isEditor && <td style={tdStyle} />}
                    </tr>
                  );
                }

                if (isDeletingThis) {
                  return (
                    <tr
                      key={code}
                      style={{ backgroundColor: "rgba(243, 139, 168, 0.1)" }}
                    >
                      <td style={tdStyle}>
                        <code style={{ fontSize: "0.85rem" }}>{code}</code>
                      </td>
                      <td style={tdStyle}>
                        <span
                          style={{
                            color: "var(--ctp-red)",
                            fontSize: "0.85rem",
                          }}
                        >
                          Delete this value?
                        </span>
                        {formError && (
                          <div
                            style={{
                              color: "var(--ctp-red)",
                              fontSize: "0.75rem",
                              marginTop: "0.25rem",
                            }}
                          >
                            {formError}
                          </div>
                        )}
                      </td>
                      <td style={tdStyle}>
                        <div style={{ display: "flex", gap: "0.25rem" }}>
                          <button
                            onClick={onDelete}
                            disabled={submitting}
                            style={{
                              ...btnTinyStyle,
                              backgroundColor: "var(--ctp-red)",
                              color: "var(--ctp-crust)",
                            }}
                          >
                            {submitting ? "..." : "Delete"}
                          </button>
                          <button onClick={onCancelEdit} style={btnTinyStyle}>
                            Cancel
                          </button>
                        </div>
                      </td>
                    </tr>
                  );
                }

                return (
                  <tr key={code}>
                    <td style={tdStyle}>
                      <code style={{ fontSize: "0.85rem" }}>{code}</code>
                    </td>
                    <td style={tdStyle}>{desc}</td>
                    {isEditor && (
                      <td style={tdStyle}>
                        <div style={{ display: "flex", gap: "0.25rem" }}>
                          <button
                            onClick={() =>
                              onStartEdit(schemaName, segment.name, code, desc)
                            }
                            style={btnTinyStyle}
                          >
                            Edit
                          </button>
                          <button
                            onClick={() =>
                              onStartDelete(schemaName, segment.name, code)
                            }
                            style={{
                              ...btnTinyStyle,
                              backgroundColor: "var(--ctp-surface2)",
                            }}
                          >
                            Delete
                          </button>
                        </div>
                      </td>
                    )}
                  </tr>
                );
              })}

              {/* Add row */}
              {isThisSegment(editState) && editState!.mode === "add" && (
                <tr>
                  <td style={tdStyle}>
                    <input
                      type="text"
                      value={editState!.code}
                      onChange={(e) =>
                        onEditStateChange({
                          ...editState!,
                          code: e.target.value,
                        })
                      }
                      placeholder="Code"
                      required
                      style={inlineInputStyle}
                      autoFocus
                    />
                  </td>
                  <td style={tdStyle}>
                    <form
                      onSubmit={onAdd}
                      style={{
                        display: "flex",
                        gap: "0.5rem",
                        alignItems: "center",
                      }}
                    >
                      <input
                        type="text"
                        value={editState!.description}
                        onChange={(e) =>
                          onEditStateChange({
                            ...editState!,
                            description: e.target.value,
                          })
                        }
                        placeholder="Description"
                        required
                        style={inlineInputStyle}
                      />
                      <button
                        type="submit"
                        disabled={submitting}
                        style={btnTinyPrimaryStyle}
                      >
                        Add
                      </button>
                      <button
                        type="button"
                        onClick={onCancelEdit}
                        style={btnTinyStyle}
                      >
                        Cancel
                      </button>
                    </form>
                    {formError && (
                      <div
                        style={{
                          color: "var(--ctp-red)",
                          fontSize: "0.75rem",
                          marginTop: "0.25rem",
                        }}
                      >
                        {formError}
                      </div>
                    )}
                  </td>
                  {isEditor && <td style={tdStyle} />}
                </tr>
              )}
            </tbody>
          </table>
        </div>
      )}

      {segment.type === "enum" &&
        isEditor &&
        !(isThisSegment(editState) && editState!.mode === "add") && (
          <button
            onClick={() => onStartAdd(schemaName, segment.name)}
            style={{ ...btnTinyPrimaryStyle, marginTop: "0.5rem" }}
          >
            + Add Value
          </button>
        )}
    </div>
  );
}

// --- Styles ---

const cardStyle: React.CSSProperties = {
  backgroundColor: "var(--ctp-surface0)",
  borderRadius: "0.75rem",
  padding: "1.25rem",
  marginBottom: "1rem",
};

const codeStyle: React.CSSProperties = {
  background: "var(--ctp-surface1)",
  padding: "0.25rem 0.5rem",
  borderRadius: "0.25rem",
  fontSize: "0.85rem",
};

const segmentStyle: React.CSSProperties = {
  marginTop: "1rem",
  padding: "1rem",
  background: "var(--ctp-base)",
  borderRadius: "0.5rem",
};

const typeBadgeStyle: React.CSSProperties = {
  display: "inline-block",
  padding: "0.15rem 0.5rem",
  borderRadius: "0.25rem",
  fontSize: "0.75rem",
  fontWeight: 600,
  backgroundColor: "rgba(166, 227, 161, 0.15)",
  color: "var(--ctp-green)",
};

const emptyStyle: React.CSSProperties = {
  textAlign: "center",
  padding: "2rem",
  color: "var(--ctp-subtext0)",
};

const thStyle: React.CSSProperties = {
  padding: "0.4rem 0.75rem",
  textAlign: "left",
  borderBottom: "1px solid var(--ctp-surface1)",
  color: "var(--ctp-subtext1)",
  fontWeight: 600,
  fontSize: "0.8rem",
  textTransform: "uppercase",
  letterSpacing: "0.05em",
};

const tdStyle: React.CSSProperties = {
  padding: "0.3rem 0.75rem",
  borderBottom: "1px solid var(--ctp-surface1)",
  fontSize: "0.85rem",
};

const btnTinyStyle: React.CSSProperties = {
  padding: "0.2rem 0.5rem",
  borderRadius: "0.25rem",
  border: "none",
  backgroundColor: "var(--ctp-surface1)",
  color: "var(--ctp-text)",
  fontSize: "0.75rem",
  cursor: "pointer",
};

const btnTinyPrimaryStyle: React.CSSProperties = {
  padding: "0.2rem 0.5rem",
  borderRadius: "0.25rem",
  border: "none",
  backgroundColor: "var(--ctp-mauve)",
  color: "var(--ctp-crust)",
  fontSize: "0.75rem",
  fontWeight: 600,
  cursor: "pointer",
};

const inlineInputStyle: React.CSSProperties = {
  padding: "0.25rem 0.5rem",
  backgroundColor: "var(--ctp-surface0)",
  border: "1px solid var(--ctp-surface1)",
  borderRadius: "0.25rem",
  color: "var(--ctp-text)",
  fontSize: "0.85rem",
  width: "100%",
  boxSizing: "border-box",
};
