import { clsx } from "clsx";
import type { StaffingRequirement, BlueprintFieldDefinition } from "@capakraken/shared";
import { BlueprintTarget, FieldType, RolePresetsSchema } from "@capakraken/shared";
import { trpc } from "~/lib/trpc/client.js";
import { InfoTooltip } from "~/components/ui/InfoTooltip.js";
import { DynamicFieldInput } from "./DynamicFieldInput.js";
import { ORDER_TYPE_OPTIONS, ALLOCATION_TYPE_OPTIONS, type WizardState } from "./types.js";

interface Step1Props {
  state: WizardState;
  onChange: (patch: Partial<WizardState>) => void;
}

export function Step1Identity({ state, onChange }: Step1Props) {
  const { data: blueprints, isLoading: blueprintsLoading } = trpc.blueprint.list.useQuery(
    { target: BlueprintTarget.PROJECT, isActive: true },
    { staleTime: 30_000 },
  ) as {
    isLoading: boolean;
    data:
      | Array<{
          id: string;
          name: string;
          description?: string | null;
          rolePresets?: unknown;
          fieldDefs?: unknown;
        }>
      | undefined;
  };

  const selectedBp = blueprints?.find((b) => b.id === state.blueprintId);

  function selectBlueprint(id: string | null) {
    if (!id) {
      onChange({
        blueprintId: null,
        blueprintName: null,
        blueprintFieldDefs: [],
        dynamicFields: {},
      });
      return;
    }
    const bp = blueprints?.find((b) => b.id === id);
    const parsedPresets = RolePresetsSchema.safeParse(
      Array.isArray(bp?.rolePresets) ? bp.rolePresets : [],
    );
    const presets = (parsedPresets.success
      ? parsedPresets.data
      : []) as unknown as StaffingRequirement[];
    const rawFieldDefs = Array.isArray(bp?.fieldDefs) ? (bp.fieldDefs as unknown[]) : [];
    const fieldDefs = rawFieldDefs.filter(
      (f): f is BlueprintFieldDefinition =>
        typeof f === "object" && f !== null && "key" in f && "type" in f && "label" in f,
    );
    const defaultDynamicFields: Record<string, unknown> = {};
    for (const field of fieldDefs) {
      if (field.defaultValue !== undefined) {
        defaultDynamicFields[field.key] = field.defaultValue;
      }
    }
    onChange({
      blueprintId: id,
      blueprintName: bp?.name ?? null,
      blueprintFieldDefs: fieldDefs,
      staffingReqs: presets,
      dynamicFields: defaultDynamicFields,
    });
  }

  return (
    <div className="space-y-5">
      {/* Blueprint picker */}
      <div>
        <label className="app-label">
          Project Blueprint (optional)
          <InfoTooltip content="Blueprints are templates that pre-fill role presets and default settings. Selecting one loads staffing requirements into Step 3." />
        </label>
        <div className="grid grid-cols-2 sm:grid-cols-3 gap-2 mb-2">
          <button
            type="button"
            onClick={() => selectBlueprint(null)}
            className={clsx(
              "text-left p-3 rounded-lg border text-sm transition-colors",
              !state.blueprintId
                ? "border-brand-500 bg-brand-50 text-brand-700"
                : "border-gray-200 hover:border-gray-300 text-gray-600",
            )}
          >
            <div className="font-medium">No Blueprint</div>
            <div className="text-xs text-gray-400 mt-0.5">Start blank</div>
          </button>
          {blueprintsLoading &&
            Array.from({ length: 3 }).map((_, i) => (
              <div
                key={i}
                className="h-16 animate-pulse rounded-lg border border-gray-200 bg-gray-100 dark:border-gray-700 dark:bg-gray-800"
              />
            ))}
          {(blueprints ?? []).map((bp) => (
            <button
              key={bp.id}
              type="button"
              onClick={() => selectBlueprint(bp.id)}
              className={clsx(
                "text-left p-3 rounded-lg border text-sm transition-colors",
                state.blueprintId === bp.id
                  ? "border-brand-500 bg-brand-50 text-brand-700"
                  : "border-gray-200 hover:border-gray-300 text-gray-600",
              )}
            >
              <div className="font-medium truncate">{bp.name}</div>
              {bp.description && (
                <div className="text-xs text-gray-400 mt-0.5 truncate">{bp.description}</div>
              )}
              {Array.isArray(bp.rolePresets) && bp.rolePresets.length > 0 && (
                <div className="text-xs text-brand-500 mt-1">
                  {bp.rolePresets.length} role preset{bp.rolePresets.length !== 1 ? "s" : ""}
                </div>
              )}
            </button>
          ))}
        </div>
        {selectedBp && (
          <p className="text-xs text-brand-600">
            Selected: <strong>{selectedBp.name}</strong>
            {Array.isArray(selectedBp.rolePresets) && selectedBp.rolePresets.length > 0
              ? ` — ${selectedBp.rolePresets.length} role presets will be loaded in Step 3`
              : ""}
          </p>
        )}
      </div>

      <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
        <div>
          <label className="app-label">
            Short Code *
            <InfoTooltip content="Unique chargecode for this project, used for time tracking and cost attribution. Must be uppercase alphanumeric." />
          </label>
          <input
            type="text"
            value={state.shortCode}
            onChange={(e) => onChange({ shortCode: e.target.value.toUpperCase() })}
            placeholder="e.g. BMW26D"
            className="app-input"
          />
          <p className="text-xs text-gray-400 mt-0.5">Uppercase alphanumeric, max 20 chars</p>
        </div>

        <div>
          <label className="app-label">
            Project Name *
            <InfoTooltip content="Display name shown on the timeline and in reports." />
          </label>
          <input
            type="text"
            value={state.name}
            onChange={(e) => onChange({ name: e.target.value })}
            placeholder="e.g. BMW X3 Campaign"
            className="app-input"
          />
        </div>

        <div>
          <label className="app-label">
            Order Type *
            <InfoTooltip content="BD = Business Development (pre-sales), CHARGEABLE = billable client work, INTERNAL = internal project, OVERHEAD = non-project overhead." />
          </label>
          <select
            value={state.orderType}
            onChange={(e) => onChange({ orderType: e.target.value })}
            className="app-select w-full"
          >
            {ORDER_TYPE_OPTIONS.map((opt) => (
              <option key={opt.value} value={opt.value}>
                {opt.label}
              </option>
            ))}
          </select>
        </div>

        <div>
          <label className="app-label">
            Allocation Type *
            <InfoTooltip content="INT = staffed with internal resources, EXT = staffed with external contractors or freelancers." />
          </label>
          <select
            value={state.allocationType}
            onChange={(e) => onChange({ allocationType: e.target.value })}
            className="app-select w-full"
          >
            {ALLOCATION_TYPE_OPTIONS.map((opt) => (
              <option key={opt.value} value={opt.value}>
                {opt.label}
              </option>
            ))}
          </select>
        </div>
      </div>

      {/* Blueprint custom fields */}
      {state.blueprintFieldDefs.length > 0 && (
        <div className="border-t border-gray-100 pt-4 space-y-3">
          <p className="text-xs font-medium text-gray-500 uppercase tracking-wider">
            Blueprint Fields — {state.blueprintName}
          </p>
          <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
            {[...state.blueprintFieldDefs]
              .sort((a, b) => a.order - b.order)
              .map((field) => (
                <div
                  key={field.key}
                  className={field.type === FieldType.TEXTAREA ? "col-span-2" : ""}
                >
                  <label className="app-label">
                    {field.label}
                    {field.required && " *"}
                    {field.description && <InfoTooltip content={field.description} />}
                  </label>
                  <DynamicFieldInput
                    field={field}
                    value={state.dynamicFields[field.key]}
                    onChange={(key, val) =>
                      onChange({ dynamicFields: { ...state.dynamicFields, [key]: val } })
                    }
                  />
                </div>
              ))}
          </div>
        </div>
      )}
    </div>
  );
}
