<script lang="ts">
  import { clientFetch } from "$lib/client-fetch";
  import ModalShell from "./ModalShell.svelte";
  import type {
    CredentialType,
    CredentialTypeField,
  } from "$lib/optima-api/modules/credentialTypes";
  import { credential } from "$lib/optima-api/modules/credentials";

  export let isOpen = false;
  export let companyId: string;
  export let accessToken: string;
  export let credentialTypes: CredentialType[] = [];
  export let onSuccess: () => void = () => {};

  let credentialName = "";
  let credentialNotes = "";
  let selectedTypeId = "";
  let fieldValues: Record<string, string> = {};
  let isSubmitting = false;
  let submitError = "";
  let isLoadingTypes = false;

  $: selectedType = credentialTypes.find((ct) => ct.id === selectedTypeId);
  $: if (selectedType && selectedType.fields) {
    fieldValues = {};
    subCredentials = {};
    selectedType.fields.forEach((field: CredentialTypeField) => {
      if (field.valueType === "multi_credential") {
        subCredentials[field.id] = [];
      } else {
        fieldValues[field.id] = "";
      }
    });
  }

  // Sub-credentials state: keyed by multi_credential field ID
  let subCredentials: Record<
    string,
    Array<{ name: string; fields: Record<string, string> }>
  > = {};

  function addSubCredentialEntry(
    fieldId: string,
    subFields: CredentialTypeField[],
  ) {
    const entry: { name: string; fields: Record<string, string> } = {
      name: "",
      fields: {},
    };
    subFields.forEach((sf) => {
      entry.fields[sf.id] = "";
    });
    subCredentials[fieldId] = [...(subCredentials[fieldId] ?? []), entry];
    subCredentials = subCredentials;
  }

  function removeSubCredentialEntry(fieldId: string, index: number) {
    subCredentials[fieldId] = subCredentials[fieldId].filter(
      (_, i) => i !== index,
    );
    subCredentials = subCredentials;
  }

  $: isValid =
    credentialName.trim().length > 0 &&
    selectedTypeId.length > 0 &&
    (!selectedType ||
      selectedType.fields.every(
        (f: CredentialTypeField) =>
          f.valueType === "multi_credential" ||
          !f.required ||
          (fieldValues[f.id] && fieldValues[f.id].trim()),
      ));

  async function loadCredentialTypes() {
    if (credentialTypes.length > 0) return;
    isLoadingTypes = true;
    try {
      const result = await clientFetch<{ data: CredentialType[] }>(
        "/api/credential-types",
      );
      if (result.data) {
        credentialTypes = Array.isArray(result.data)
          ? result.data
          : [result.data];
      }
    } catch (err) {
      console.error("Failed to load credential types:", err);
      submitError = "Failed to load credential types";
    } finally {
      isLoadingTypes = false;
    }
  }

  async function handleSubmit() {
    if (!isValid || !selectedType) return;

    isSubmitting = true;
    submitError = "";

    try {
      const fields = selectedType.fields
        .filter(
          (field: CredentialTypeField) =>
            field.valueType !== "multi_credential",
        )
        .map((field: CredentialTypeField) => ({
          fieldId: field.id,
          value: fieldValues[field.id] || "",
        }));

      // Build subCredentials payload for multi_credential fields
      const subCredsPayload: Record<
        string,
        Array<{
          name: string;
          fields: Array<{ fieldId: string; value: string }>;
        }>
      > = {};
      for (const [fieldId, entries] of Object.entries(subCredentials)) {
        if (entries.length > 0) {
          subCredsPayload[fieldId] = entries.map((entry) => ({
            name: entry.name,
            fields: Object.entries(entry.fields).map(([fid, val]) => ({
              fieldId: fid,
              value: val,
            })),
          }));
        }
      }

      const createPayload: Record<string, unknown> = {
        name: credentialName,
        notes: credentialNotes || undefined,
        typeId: selectedTypeId,
        companyId,
        fields,
      };
      if (Object.keys(subCredsPayload).length > 0) {
        createPayload.subCredentials = subCredsPayload;
      }

      await credential.create(
        accessToken,
        createPayload as unknown as Omit<
          import("$lib/optima-api/modules/credentials").Credential,
          "id" | "createdAt" | "updatedAt"
        >,
      );

      reset();
      onSuccess();
    } catch (err) {
      submitError =
        err instanceof Error ? err.message : "Failed to create credential";
      console.error("Failed to create credential:", err);
    } finally {
      isSubmitting = false;
    }
  }

  function reset() {
    credentialName = "";
    credentialNotes = "";
    selectedTypeId = "";
    fieldValues = {};
    subCredentials = {};
    isSubmitting = false;
    submitError = "";
  }

  function handleClose() {
    reset();
    isOpen = false;
  }

  $: if (isOpen) {
    loadCredentialTypes();
  }
</script>

<ModalShell {isOpen} title="Create Credential" onClose={handleClose}>
  <svelte:fragment slot="icon">
    <svg
      viewBox="0 0 24 24"
      fill="none"
      stroke="currentColor"
      stroke-width="2"
      width="18"
      height="18"
    >
      <rect x="3" y="11" width="18" height="11" rx="2" ry="2" />
      <path d="M7 11V7a5 5 0 0 1 10 0v4" />
    </svg>
  </svelte:fragment>

  <div class="modal-body">
    {#if submitError}
      <div class="error-banner">
        <svg
          viewBox="0 0 24 24"
          fill="none"
          stroke="currentColor"
          stroke-width="2"
          width="14"
          height="14"
        >
          <circle cx="12" cy="12" r="10" />
          <line x1="12" y1="8" x2="12" y2="12" />
          <line x1="12" y1="16" x2="12.01" y2="16" />
        </svg>
        {submitError}
      </div>
    {/if}

    <div class="form-row">
      <div class="form-group">
        <label for="credential-name">
          Name <span class="req">*</span>
        </label>
        <input
          id="credential-name"
          type="text"
          bind:value={credentialName}
          placeholder="e.g. Production AWS Credentials"
          disabled={isSubmitting}
        />
      </div>
      <div class="form-group">
        <label for="credential-type">
          Credential Type <span class="req">*</span>
        </label>
        {#if isLoadingTypes}
          <div class="loading-wrap">
            <svg viewBox="0 0 24 24" width="14" height="14" class="spin-icon">
              <circle
                cx="12"
                cy="12"
                r="10"
                stroke="currentColor"
                stroke-width="3"
                fill="none"
                opacity="0.25"
              />
              <path
                d="M12 2a10 10 0 0 1 10 10"
                stroke="currentColor"
                stroke-width="3"
                fill="none"
                stroke-linecap="round"
              />
            </svg>
            <span>Loading types…</span>
          </div>
        {:else}
          <select
            id="credential-type"
            bind:value={selectedTypeId}
            disabled={isSubmitting}
          >
            <option value="">Select a type</option>
            {#each credentialTypes as type (type.id)}
              <option value={type.id}>{type.name}</option>
            {/each}
          </select>
        {/if}
      </div>
    </div>

    <div class="form-group">
      <label for="credential-notes">Notes</label>
      <textarea
        id="credential-notes"
        bind:value={credentialNotes}
        placeholder="Optional notes about this credential"
        disabled={isSubmitting}
        rows="2"
        class="notes-textarea"
      ></textarea>
    </div>

    {#if selectedType && selectedType.fields && selectedType.fields.length > 0}
      <div class="fields-section">
        <div class="fields-section-header">
          <span class="fields-label">Credential Fields</span>
          <span class="fields-badge">
            {selectedType.fields.length} field{selectedType.fields.length === 1
              ? ""
              : "s"}
          </span>
        </div>
        <div class="fields-list">
          {#each selectedType.fields as field (field.id)}
            <div class="field-card">
              <div class="field-card-header">
                <span class="field-name-label">{field.name}</span>
                <div class="field-header-badges">
                  {#if field.valueType === "multi_credential"}
                    <span class="field-badge field-badge-multi">
                      <svg
                        viewBox="0 0 24 24"
                        fill="none"
                        stroke="currentColor"
                        stroke-width="2"
                        width="10"
                        height="10"
                      >
                        <rect x="2" y="3" width="20" height="6" rx="1" />
                        <rect x="2" y="15" width="20" height="6" rx="1" />
                        <path d="M12 9v6" />
                      </svg>
                      Multi
                    </span>
                  {/if}
                  {#if field.required}
                    <span class="field-badge field-badge-required"
                      >Required</span
                    >
                  {/if}
                  {#if field.secure}
                    <span class="field-badge field-badge-secure">
                      <svg
                        viewBox="0 0 24 24"
                        fill="none"
                        stroke="currentColor"
                        stroke-width="2"
                        width="10"
                        height="10"
                      >
                        <rect
                          x="3"
                          y="11"
                          width="18"
                          height="11"
                          rx="2"
                          ry="2"
                        />
                        <path d="M7 11V7a5 5 0 0 1 10 0v4" />
                      </svg>
                      Secure
                    </span>
                  {/if}
                </div>
              </div>
              <div class="field-card-body">
                {#if field.valueType === "multi_credential" && field.subFields}
                  <!-- Multi-credential entries -->
                  <div class="multi-cred-section">
                    {#if (subCredentials[field.id] ?? []).length === 0}
                      <p class="multi-cred-empty">
                        No entries yet. Add an entry to define sub-credentials
                        for this field.
                      </p>
                    {:else}
                      {#each subCredentials[field.id] as entry, entryIdx}
                        <div class="multi-cred-entry">
                          <div class="multi-cred-entry-header">
                            <span class="multi-cred-entry-num"
                              >#{entryIdx + 1}</span
                            >
                            <button
                              type="button"
                              class="multi-cred-entry-remove"
                              on:click={() =>
                                removeSubCredentialEntry(field.id, entryIdx)}
                              disabled={isSubmitting}
                              aria-label="Remove entry"
                            >
                              <svg
                                viewBox="0 0 24 24"
                                fill="none"
                                stroke="currentColor"
                                stroke-width="2"
                                width="13"
                                height="13"
                              >
                                <line x1="18" y1="6" x2="6" y2="18" /><line
                                  x1="6"
                                  y1="6"
                                  x2="18"
                                  y2="18"
                                />
                              </svg>
                            </button>
                          </div>
                          <div class="multi-cred-entry-body">
                            <div class="multi-cred-entry-field">
                              <label for="sub-cred-name-{field.id}-{entryIdx}"
                                >Entry Name <span class="req">*</span></label
                              >
                              <input
                                id="sub-cred-name-{field.id}-{entryIdx}"
                                type="text"
                                bind:value={entry.name}
                                placeholder="e.g. Tunnel 1"
                                disabled={isSubmitting}
                              />
                            </div>
                            {#each field.subFields as subField (subField.id)}
                              <div class="multi-cred-entry-field">
                                <label
                                  for="sub-cred-{field.id}-{entryIdx}-{subField.id}"
                                >
                                  {subField.name}
                                  {#if subField.required}<span class="req"
                                      >*</span
                                    >{/if}
                                  {#if subField.secure}
                                    <svg
                                      class="sub-cred-lock"
                                      viewBox="0 0 24 24"
                                      fill="none"
                                      stroke="currentColor"
                                      stroke-width="2"
                                      width="10"
                                      height="10"
                                    >
                                      <rect
                                        x="3"
                                        y="11"
                                        width="18"
                                        height="11"
                                        rx="2"
                                        ry="2"
                                      />
                                      <path d="M7 11V7a5 5 0 0 1 10 0v4" />
                                    </svg>
                                  {/if}
                                </label>
                                <input
                                  id="sub-cred-{field.id}-{entryIdx}-{subField.id}"
                                  type="text"
                                  bind:value={entry.fields[subField.id]}
                                  placeholder="Enter {subField.name.toLowerCase()}"
                                  disabled={isSubmitting}
                                />
                              </div>
                            {/each}
                          </div>
                        </div>
                      {/each}
                    {/if}
                    <button
                      type="button"
                      class="multi-cred-add-btn"
                      on:click={() =>
                        addSubCredentialEntry(field.id, field.subFields ?? [])}
                      disabled={isSubmitting}
                    >
                      <svg
                        viewBox="0 0 24 24"
                        fill="none"
                        stroke="currentColor"
                        stroke-width="2"
                        width="12"
                        height="12"
                      >
                        <line x1="12" y1="5" x2="12" y2="19" /><line
                          x1="5"
                          y1="12"
                          x2="19"
                          y2="12"
                        />
                      </svg>
                      Add Entry
                    </button>
                  </div>
                {:else}
                  <input
                    id="field-{field.id}"
                    type="text"
                    bind:value={fieldValues[field.id]}
                    placeholder="Enter {field.name.toLowerCase()}"
                    disabled={isSubmitting}
                  />
                {/if}
              </div>
            </div>
          {/each}
        </div>
      </div>
    {/if}
  </div>

  <div class="modal-footer">
    <button
      type="button"
      class="btn-cancel"
      on:click={handleClose}
      disabled={isSubmitting}
    >
      Cancel
    </button>
    <button
      type="button"
      class="btn-submit"
      on:click={handleSubmit}
      disabled={!isValid || isSubmitting}
    >
      {isSubmitting ? "Creating…" : "Create Credential"}
    </button>
  </div>
</ModalShell>

<style>
  /* ── Body ── */
  .modal-body {
    padding: 18px 22px;
    overflow-y: auto;
    flex: 1;
  }

  /* ── Error banner ── */
  .error-banner {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px 14px;
    margin-bottom: 16px;
    background: rgba(220, 38, 38, 0.08);
    border: 1px solid rgba(220, 38, 38, 0.2);
    border-radius: 8px;
    font-size: 13px;
    color: #dc2626;
  }

  /* ── Form layout ── */
  .form-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 14px;
    margin-bottom: 14px;
  }

  .form-group {
    display: flex;
    flex-direction: column;
    gap: 5px;
    margin-bottom: 14px;
  }

  .form-row .form-group {
    margin-bottom: 0;
  }

  label {
    font-size: 12.5px;
    font-weight: 600;
    color: var(--text-secondary);
  }

  .req {
    color: #dc2626;
  }

  input[type="text"],
  select {
    width: 100%;
    padding: 7px 10px;
    border: 1px solid var(--border-subtle);
    border-radius: 7px;
    background: var(--bg-inset);
    font-size: 13px;
    color: var(--text-primary);
    box-sizing: border-box;
    transition:
      border-color 0.15s,
      box-shadow 0.15s;
  }

  input[type="text"]:focus,
  select:focus {
    outline: none;
    border-color: var(--input-focus-border);
    box-shadow: 0 0 0 3px rgba(0, 102, 204, 0.1);
  }

  input[type="text"]::placeholder {
    color: var(--text-muted);
  }

  .notes-textarea {
    width: 100%;
    padding: 7px 10px;
    border: 1px solid var(--border-subtle);
    border-radius: 7px;
    background: var(--bg-inset);
    font-size: 13px;
    color: var(--text-primary);
    box-sizing: border-box;
    resize: vertical;
    font-family: inherit;
    transition:
      border-color 0.15s,
      box-shadow 0.15s;
  }

  .notes-textarea:focus {
    outline: none;
    border-color: var(--input-focus-border);
    box-shadow: 0 0 0 3px rgba(0, 102, 204, 0.1);
  }

  .notes-textarea::placeholder {
    color: var(--text-muted);
  }

  .notes-textarea:disabled {
    opacity: 0.6;
    cursor: not-allowed;
  }

  input:disabled,
  select:disabled {
    opacity: 0.5;
    cursor: not-allowed;
  }

  /* ── Loading indicator ── */
  .loading-wrap {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 7px 10px;
    border: 1px solid var(--border-subtle);
    border-radius: 7px;
    background: var(--bg-inset);
    font-size: 13px;
    color: var(--text-muted);
  }

  .spin-icon {
    animation: spin 0.8s linear infinite;
    color: var(--text-muted);
  }

  /* ── Fields section ── */
  .fields-section {
    margin-top: 4px;
  }

  .fields-section-header {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 10px;
  }

  .fields-label {
    font-size: 13px;
    font-weight: 600;
    color: var(--text-primary);
  }

  .fields-badge {
    font-size: 11px;
    font-weight: 500;
    padding: 2px 8px;
    border-radius: 8px;
    background: var(--status-neutral-bg);
    color: var(--text-secondary);
    border: 1px solid var(--border-subtle);
  }

  .fields-list {
    display: flex;
    flex-direction: column;
    gap: 10px;
  }

  .field-card {
    border: 1px solid var(--border-subtle);
    border-radius: 9px;
    background: var(--bg-inset);
    overflow: hidden;
  }

  .field-card-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 8px 12px;
    background: var(--bg-surface);
    border-bottom: 1px solid var(--border-subtle);
  }

  .field-name-label {
    font-size: 12.5px;
    font-weight: 600;
    color: var(--text-primary);
  }

  .field-header-badges {
    display: flex;
    align-items: center;
    gap: 6px;
  }

  .field-badge {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    font-size: 10px;
    font-weight: 600;
    padding: 2px 7px;
    border-radius: 6px;
    letter-spacing: 0.02em;
    text-transform: uppercase;
  }

  .field-badge-required {
    background: rgba(220, 38, 38, 0.08);
    color: #dc2626;
    border: 1px solid rgba(220, 38, 38, 0.15);
  }

  .field-badge-secure {
    background: rgba(59, 130, 246, 0.08);
    color: #3b82f6;
    border: 1px solid rgba(59, 130, 246, 0.15);
  }

  .field-card-body {
    padding: 10px 12px;
  }

  .field-card-body input {
    margin: 0;
  }

  /* ── Multi-credential entries ── */
  .multi-cred-section {
    display: flex;
    flex-direction: column;
    gap: 8px;
  }

  .multi-cred-empty {
    margin: 0;
    font-size: 12px;
    color: var(--text-muted);
    line-height: 1.5;
  }

  .multi-cred-entry {
    border: 1px solid var(--border-subtle);
    border-radius: 7px;
    background: var(--bg-surface);
    overflow: hidden;
  }

  .multi-cred-entry-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 5px 10px;
    background: var(--bg-inset);
    border-bottom: 1px solid var(--border-subtle);
  }

  .multi-cred-entry-num {
    font-size: 11px;
    font-weight: 600;
    color: var(--text-muted);
  }

  .multi-cred-entry-remove {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    padding: 0;
    background: none;
    border: 1px solid transparent;
    border-radius: 5px;
    cursor: pointer;
    color: var(--text-muted);
    transition:
      background 0.1s,
      color 0.1s;
  }

  .multi-cred-entry-remove:hover:not(:disabled) {
    background: rgba(220, 38, 38, 0.08);
    color: #dc2626;
  }

  .multi-cred-entry-remove:disabled {
    opacity: 0.4;
    cursor: not-allowed;
  }

  .multi-cred-entry-body {
    padding: 10px;
    display: flex;
    flex-direction: column;
    gap: 8px;
  }

  .multi-cred-entry-field {
    display: flex;
    flex-direction: column;
    gap: 4px;
  }

  .multi-cred-entry-field label {
    display: flex;
    align-items: center;
    gap: 4px;
  }

  .sub-cred-lock {
    color: var(--text-muted);
    flex-shrink: 0;
  }

  .multi-cred-add-btn {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 5px 14px;
    background: none;
    border: 1px dashed var(--border-subtle);
    border-radius: 6px;
    font-size: 12px;
    font-weight: 500;
    color: var(--text-muted);
    cursor: pointer;
    transition:
      background 0.12s,
      border-color 0.12s,
      color 0.12s;
    align-self: flex-start;
  }

  .multi-cred-add-btn:hover:not(:disabled) {
    background: var(--card-hover-bg);
    border-color: var(--accent-color, #0066cc);
    color: var(--text-primary);
  }

  .multi-cred-add-btn:disabled {
    opacity: 0.4;
    cursor: not-allowed;
  }

  .field-badge-multi {
    background: rgba(139, 92, 246, 0.08);
    color: #8b5cf6;
    border: 1px solid rgba(139, 92, 246, 0.15);
  }

  /* ── Footer ── */
  .modal-footer {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 8px;
    padding: 14px 22px;
    border-top: 1px solid var(--border-subtle);
    flex-shrink: 0;
  }

  .btn-cancel {
    padding: 7px 16px;
    border-radius: 7px;
    font-size: 13px;
    font-weight: 500;
    cursor: pointer;
    background: var(--bg-inset);
    border: 1px solid var(--border-subtle);
    color: var(--text-secondary);
    transition:
      background 0.15s,
      border-color 0.15s;
  }

  .btn-cancel:hover:not(:disabled) {
    background: var(--card-hover-bg);
    border-color: var(--border-default);
    color: var(--text-primary);
  }

  .btn-cancel:disabled {
    opacity: 0.45;
    cursor: not-allowed;
  }

  .btn-submit {
    padding: 7px 18px;
    border-radius: 7px;
    font-size: 13px;
    font-weight: 500;
    cursor: pointer;
    background: var(--accent-color, #0066cc);
    border: 1px solid transparent;
    color: #fff;
    transition: filter 0.15s;
  }

  .btn-submit:hover:not(:disabled) {
    filter: brightness(1.1);
  }

  .btn-submit:disabled {
    opacity: 0.45;
    cursor: not-allowed;
  }

  @keyframes spin {
    to {
      transform: rotate(360deg);
    }
  }

  /* ── Mobile fixes ── */
  @media (max-width: 768px) {
    .modal-body {
      padding: 14px 16px;
    }

    .modal-footer {
      padding: 12px 16px;
    }

    /* Prevent iOS zoom on focus — inputs/selects must be >= 16px */
    input[type="text"],
    select {
      font-size: 16px;
      padding: 10px 12px;
      border-radius: 8px;
    }

    select {
      -webkit-appearance: none;
      appearance: none;
      background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23888' stroke-width='2.5'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
      background-repeat: no-repeat;
      background-position: right 12px center;
      padding-right: 32px;
    }

    /* Stack name + type vertically on mobile */
    .form-row {
      grid-template-columns: 1fr;
      gap: 4px;
    }

    label {
      font-size: 13px;
    }

    .field-card-body input {
      font-size: 16px;
      padding: 10px 12px;
    }

    .field-name-label {
      font-size: 13px;
    }

    .btn-cancel,
    .btn-submit {
      padding: 10px 18px;
      font-size: 14px;
    }
  }
</style>
