<script lang="ts">
  import { unifi, type UnifiSite } from "$lib/optima-api/modules/unifi";

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

  type ModalStep = "choose" | "existing" | "new";
  let step: ModalStep = "choose";

  // Existing site linking
  let allSites: UnifiSite[] = [];
  let isLoadingSites = false;
  let selectedSiteId = "";
  let isLinking = false;
  let linkError = "";
  let siteSearch = "";

  // New site creation
  let newSiteName = "";
  let isCreating = false;
  let createError = "";

  function reset() {
    step = "choose";
    allSites = [];
    isLoadingSites = false;
    selectedSiteId = "";
    isLinking = false;
    linkError = "";
    siteSearch = "";
    newSiteName = "";
    isCreating = false;
    createError = "";
  }

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

  async function goToExisting() {
    step = "existing";
    linkError = "";
    isLoadingSites = true;
    try {
      const result = await unifi.fetchSites(accessToken);
      // Filter out sites already linked to this company
      allSites = (result?.data ?? []).filter(
        (s: UnifiSite) => !linkedSiteIds.includes(s.id),
      );
    } catch (err) {
      console.error("Failed to fetch UniFi sites:", err);
      linkError = err instanceof Error ? err.message : "Failed to load sites";
      allSites = [];
    } finally {
      isLoadingSites = false;
    }
  }

  function goToNew() {
    step = "new";
    createError = "";
    newSiteName = "";
  }

  function goBack() {
    step = "choose";
    linkError = "";
    createError = "";
  }

  async function linkExistingSite() {
    if (!selectedSiteId || !accessToken) return;
    isLinking = true;
    linkError = "";
    try {
      await unifi.linkSite(accessToken, selectedSiteId, companyId);
      close();
      onSuccess();
    } catch (err) {
      linkError = err instanceof Error ? err.message : "Failed to link site";
      console.error("Failed to link UniFi site:", err);
    } finally {
      isLinking = false;
    }
  }

  async function createAndLinkSite() {
    if (!newSiteName.trim() || !accessToken) return;
    isCreating = true;
    createError = "";
    try {
      const result = await unifi.createSite(accessToken, newSiteName.trim());
      const newSiteId = result?.data?.id;
      if (newSiteId && companyId) {
        await unifi.linkSite(accessToken, newSiteId, companyId);
      }
      close();
      onSuccess();
    } catch (err) {
      createError =
        err instanceof Error ? err.message : "Failed to create site";
      console.error("Failed to create UniFi site:", err);
    } finally {
      isCreating = false;
    }
  }

  // Filter sites that are unlinked (no company) or linked to a different company
  $: availableSites = allSites.filter(
    (s) => !s.companyId || s.companyId !== companyId,
  );
  $: unlinkedSites = availableSites.filter((s) => !s.companyId);
  $: otherCompanySites = availableSites.filter(
    (s) => s.companyId && s.companyId !== companyId,
  );

  // Search-filtered lists
  $: filteredUnlinked = siteSearch.trim()
    ? unlinkedSites.filter((s) => {
        const q = siteSearch.trim().toLowerCase();
        return (
          s.name.toLowerCase().includes(q) || s.siteId.toLowerCase().includes(q)
        );
      })
    : unlinkedSites;
  $: filteredOtherCompany = siteSearch.trim()
    ? otherCompanySites.filter((s) => {
        const q = siteSearch.trim().toLowerCase();
        return (
          s.name.toLowerCase().includes(q) ||
          s.siteId.toLowerCase().includes(q) ||
          (s.company?.name ?? "").toLowerCase().includes(q)
        );
      })
    : otherCompanySites;
  $: totalFiltered = filteredUnlinked.length + filteredOtherCompany.length;
</script>

{#if isOpen}
  <!-- svelte-ignore a11y_no_static_element_interactions -->
  <!-- svelte-ignore a11y_click_events_have_key_events -->
  <div class="modal-overlay" on:click={close}>
    <!-- svelte-ignore a11y_no_static_element_interactions -->
    <!-- svelte-ignore a11y_click_events_have_key_events -->
    <div class="modal-container" on:click|stopPropagation>
      <div class="modal-header">
        {#if step !== "choose"}
          <button
            class="modal-back"
            on:click={goBack}
            type="button"
            aria-label="Back"
          >
            <svg
              viewBox="0 0 24 24"
              fill="none"
              stroke="currentColor"
              stroke-width="2"
              width="16"
              height="16"
            >
              <path d="M19 12H5M12 19l-7-7 7-7" />
            </svg>
          </button>
        {/if}
        <h3 class="modal-title">
          <svg
            viewBox="0 0 24 24"
            fill="none"
            stroke="currentColor"
            stroke-width="2"
            width="18"
            height="18"
          >
            <path d="M12 2L2 7l10 5 10-5-10-5z" />
            <path d="M2 17l10 5 10-5" />
            <path d="M2 12l10 5 10-5" />
          </svg>
          {#if step === "choose"}
            Link UniFi Site
          {:else if step === "existing"}
            Link Existing Site
          {:else}
            Create New Site
          {/if}
        </h3>
        <button
          class="modal-close"
          on:click={close}
          type="button"
          aria-label="Close"
        >
          <svg
            viewBox="0 0 24 24"
            fill="none"
            stroke="currentColor"
            stroke-width="2"
            width="16"
            height="16"
          >
            <path d="M18 6L6 18M6 6l12 12" />
          </svg>
        </button>
      </div>

      <div class="modal-body">
        {#if step === "choose"}
          <p class="modal-description">
            How would you like to add a UniFi site?
          </p>
          <div class="choice-grid">
            <button class="choice-card" on:click={goToNew} type="button">
              <div class="choice-icon">
                <svg
                  viewBox="0 0 24 24"
                  fill="none"
                  stroke="currentColor"
                  stroke-width="1.5"
                  width="28"
                  height="28"
                >
                  <circle cx="12" cy="12" r="10" />
                  <line x1="12" y1="8" x2="12" y2="16" />
                  <line x1="8" y1="12" x2="16" y2="12" />
                </svg>
              </div>
              <span class="choice-label">New Site</span>
              <span class="choice-desc"
                >Create a new site on the UniFi controller</span
              >
            </button>
            <button class="choice-card" on:click={goToExisting} type="button">
              <div class="choice-icon">
                <svg
                  viewBox="0 0 24 24"
                  fill="none"
                  stroke="currentColor"
                  stroke-width="1.5"
                  width="28"
                  height="28"
                >
                  <path
                    d="M10 13a5 5 0 007.54.54l3-3a5 5 0 00-7.07-7.07l-1.72 1.71"
                  />
                  <path
                    d="M14 11a5 5 0 00-7.54-.54l-3 3a5 5 0 007.07 7.07l1.71-1.71"
                  />
                </svg>
              </div>
              <span class="choice-label">Existing Site</span>
              <span class="choice-desc"
                >Link an existing UniFi site to this company</span
              >
            </button>
          </div>
        {:else if step === "existing"}
          {#if isLoadingSites}
            <div class="modal-loading">
              <svg viewBox="0 0 24 24" width="20" height="20" 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 sites…</span>
            </div>
          {:else if availableSites.length === 0}
            <div class="modal-empty">
              <svg
                viewBox="0 0 24 24"
                fill="none"
                stroke="currentColor"
                stroke-width="1.5"
                width="32"
                height="32"
              >
                <path d="M12 2L2 7l10 5 10-5-10-5z" />
                <path d="M2 17l10 5 10-5" />
                <path d="M2 12l10 5 10-5" />
              </svg>
              <p>No available sites to link</p>
              <span class="modal-empty-hint"
                >All sites are already linked to this company, or no sites
                exist.</span
              >
            </div>
          {:else}
            <!-- Search input -->
            <div class="site-search-bar">
              <svg
                class="site-search-icon"
                viewBox="0 0 24 24"
                fill="none"
                stroke="currentColor"
                stroke-width="2"
                width="14"
                height="14"
              >
                <circle cx="11" cy="11" r="8" />
                <line x1="21" y1="21" x2="16.65" y2="16.65" />
              </svg>
              <input
                class="site-search-input"
                type="text"
                placeholder="Search sites…"
                bind:value={siteSearch}
                disabled={isLinking}
              />
              {#if siteSearch}
                <button
                  class="site-search-clear"
                  type="button"
                  on:click={() => (siteSearch = "")}
                  aria-label="Clear search"
                >
                  <svg
                    viewBox="0 0 24 24"
                    fill="none"
                    stroke="currentColor"
                    stroke-width="2"
                    width="12"
                    height="12"
                  >
                    <path d="M18 6L6 18M6 6l12 12" />
                  </svg>
                </button>
              {/if}
            </div>

            <!-- Scrollable site list -->
            <div class="site-list">
              {#if totalFiltered === 0}
                <div class="site-list-empty">
                  <p>No sites matching "{siteSearch}"</p>
                </div>
              {:else}
                {#if filteredUnlinked.length > 0}
                  <div class="site-list-group-label">Unlinked Sites</div>
                  {#each filteredUnlinked as site (site.id)}
                    <button
                      class="site-list-item"
                      class:selected={selectedSiteId === site.id}
                      type="button"
                      on:click={() => (selectedSiteId = site.id)}
                      disabled={isLinking}
                    >
                      <div class="site-list-item-icon">
                        <svg
                          viewBox="0 0 24 24"
                          fill="none"
                          stroke="currentColor"
                          stroke-width="1.5"
                          width="18"
                          height="18"
                        >
                          <path d="M12 2L2 7l10 5 10-5-10-5z" />
                          <path d="M2 17l10 5 10-5" />
                          <path d="M2 12l10 5 10-5" />
                        </svg>
                      </div>
                      <div class="site-list-item-info">
                        <span class="site-list-item-name">{site.name}</span>
                        <span class="site-list-item-id">{site.siteId}</span>
                      </div>
                      {#if selectedSiteId === site.id}
                        <svg
                          class="site-list-item-check"
                          viewBox="0 0 24 24"
                          fill="none"
                          stroke="currentColor"
                          stroke-width="2.5"
                          width="16"
                          height="16"
                        >
                          <polyline points="20 6 9 17 4 12" />
                        </svg>
                      {/if}
                    </button>
                  {/each}
                {/if}
                {#if filteredOtherCompany.length > 0}
                  <div class="site-list-group-label">
                    Linked to Other Companies
                  </div>
                  {#each filteredOtherCompany as site (site.id)}
                    <button
                      class="site-list-item"
                      class:selected={selectedSiteId === site.id}
                      type="button"
                      on:click={() => (selectedSiteId = site.id)}
                      disabled={isLinking}
                    >
                      <div class="site-list-item-icon">
                        <svg
                          viewBox="0 0 24 24"
                          fill="none"
                          stroke="currentColor"
                          stroke-width="1.5"
                          width="18"
                          height="18"
                        >
                          <path d="M12 2L2 7l10 5 10-5-10-5z" />
                          <path d="M2 17l10 5 10-5" />
                          <path d="M2 12l10 5 10-5" />
                        </svg>
                      </div>
                      <div class="site-list-item-info">
                        <span class="site-list-item-name">{site.name}</span>
                        <span class="site-list-item-id"
                          >{site.company?.name ?? "Unknown"}</span
                        >
                      </div>
                      {#if selectedSiteId === site.id}
                        <svg
                          class="site-list-item-check"
                          viewBox="0 0 24 24"
                          fill="none"
                          stroke="currentColor"
                          stroke-width="2.5"
                          width="16"
                          height="16"
                        >
                          <polyline points="20 6 9 17 4 12" />
                        </svg>
                      {/if}
                    </button>
                  {/each}
                {/if}
              {/if}
            </div>

            {#if linkError}
              <div class="modal-error">
                <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>
                {linkError}
              </div>
            {/if}
          {/if}
        {:else if step === "new"}
          <div class="modal-field">
            <label class="modal-label" for="new-unifi-site-name"
              >Site Name</label
            >
            <input
              id="new-unifi-site-name"
              class="modal-input"
              type="text"
              bind:value={newSiteName}
              placeholder="e.g. Main Office"
              disabled={isCreating}
            />
          </div>
          {#if createError}
            <div class="modal-error">
              <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>
              {createError}
            </div>
          {/if}
        {/if}
      </div>

      {#if step !== "choose"}
        <div class="modal-footer">
          <button
            class="modal-btn modal-btn-cancel"
            on:click={close}
            type="button"
            disabled={isLinking || isCreating}
          >
            Cancel
          </button>
          {#if step === "existing"}
            <button
              class="modal-btn modal-btn-primary"
              on:click={linkExistingSite}
              type="button"
              disabled={isLinking || !selectedSiteId}
            >
              {isLinking ? "Linking…" : "Link Site"}
            </button>
          {:else if step === "new"}
            <button
              class="modal-btn modal-btn-primary"
              on:click={createAndLinkSite}
              type="button"
              disabled={isCreating || !newSiteName.trim()}
            >
              {isCreating ? "Creating…" : "Create & Link"}
            </button>
          {/if}
        </div>
      {/if}
    </div>
  </div>
{/if}

<style>
  .modal-overlay {
    position: fixed;
    inset: 0;
    z-index: 1000;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(0, 0, 0, 0.5);
    backdrop-filter: blur(4px);
  }

  .modal-container {
    width: 480px;
    max-width: 90vw;
    background: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: 12px;
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
    overflow: hidden;
  }

  .modal-header {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 16px 20px;
    border-bottom: 1px solid var(--border-subtle);
  }

  .modal-title {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0;
    font-size: 15px;
    font-weight: 600;
    color: var(--text-primary);
    flex: 1;
  }

  .modal-back {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border: 1px solid var(--border-subtle);
    border-radius: 6px;
    background: none;
    color: var(--text-secondary);
    cursor: pointer;
    transition: all 0.15s;
    flex-shrink: 0;
  }

  .modal-back:hover {
    background: var(--nav-hover-bg);
    color: var(--text-primary);
  }

  .modal-close {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border: none;
    border-radius: 6px;
    background: none;
    color: var(--text-secondary);
    cursor: pointer;
    transition: all 0.15s;
    flex-shrink: 0;
  }

  .modal-close:hover {
    background: var(--nav-hover-bg);
    color: var(--text-primary);
  }

  .modal-body {
    padding: 20px;
    display: flex;
    flex-direction: column;
    gap: 16px;
  }

  .modal-description {
    margin: 0;
    font-size: 13px;
    color: var(--text-secondary);
  }

  /* Choice cards */
  .choice-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
  }

  .choice-card {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    padding: 24px 16px;
    border: 1px solid var(--border-subtle);
    border-radius: 10px;
    background: var(--bg-base);
    cursor: pointer;
    transition: all 0.2s;
    text-align: center;
  }

  .choice-card:hover {
    border-color: var(--input-focus-border);
    background: color-mix(
      in srgb,
      var(--input-focus-border) 5%,
      var(--bg-base)
    );
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
  }

  .choice-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 48px;
    height: 48px;
    border-radius: 12px;
    background: color-mix(in srgb, var(--input-focus-border) 10%, transparent);
    color: var(--input-focus-border);
  }

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

  .choice-desc {
    font-size: 11px;
    color: var(--text-muted);
    line-height: 1.4;
  }

  /* Form fields */
  .modal-field {
    display: flex;
    flex-direction: column;
    gap: 6px;
  }

  .modal-label {
    font-size: 12px;
    font-weight: 600;
    color: var(--text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.03em;
  }

  .modal-input {
    padding: 8px 12px;
    font-size: 13px;
    border: 1px solid var(--border-default);
    border-radius: 6px;
    background: var(--bg-base);
    color: var(--text-primary);
    outline: none;
    transition: border-color 0.15s;
  }

  .modal-input:focus {
    border-color: var(--input-focus-border);
    box-shadow: 0 0 0 2px
      color-mix(in srgb, var(--input-focus-border) 15%, transparent);
  }

  .modal-input:disabled {
    opacity: 0.6;
    cursor: not-allowed;
  }

  .modal-error {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 8px 12px;
    border-radius: 6px;
    background: color-mix(in srgb, var(--status-error) 10%, transparent);
    color: var(--status-error);
    font-size: 12px;
    font-weight: 500;
  }

  .modal-loading {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    padding: 32px;
    color: var(--text-secondary);
    font-size: 13px;
  }

  .modal-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    padding: 24px;
    color: var(--text-secondary);
    font-size: 13px;
    text-align: center;
  }

  .modal-empty p {
    margin: 0;
    font-weight: 500;
  }

  .modal-empty-hint {
    font-size: 11px;
    color: var(--text-muted);
  }

  .modal-footer {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
    padding: 16px 20px;
    border-top: 1px solid var(--border-subtle);
  }

  .modal-btn {
    padding: 7px 16px;
    font-size: 12px;
    font-weight: 500;
    border-radius: 6px;
    cursor: pointer;
    transition: all 0.15s;
  }

  .modal-btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
  }

  .modal-btn-cancel {
    background: var(--bg-surface);
    color: var(--text-secondary);
    border: 1px solid var(--border-default);
  }

  .modal-btn-cancel:hover:not(:disabled) {
    background: var(--nav-hover-bg);
  }

  .modal-btn-primary {
    background: var(--accent-color, #0066cc);
    color: #fff;
    border: none;
  }

  .modal-btn-primary:hover:not(:disabled) {
    filter: brightness(1.12);
  }

  /* Site search bar */
  .site-search-bar {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 7px 10px;
    background: var(--bg-base);
    border: 1px solid var(--border-subtle);
    border-radius: 6px;
    transition: border-color 0.15s;
  }

  .site-search-bar:focus-within {
    border-color: var(--input-focus-border);
    box-shadow: 0 0 0 2px
      color-mix(in srgb, var(--input-focus-border) 12%, transparent);
  }

  .site-search-icon {
    color: var(--text-muted);
    flex-shrink: 0;
  }

  .site-search-bar:focus-within .site-search-icon {
    color: var(--input-focus-border);
  }

  .site-search-input {
    flex: 1;
    min-width: 0;
    border: none;
    background: transparent;
    font-size: 13px;
    color: var(--text-primary);
    outline: none;
  }

  .site-search-input::placeholder {
    color: var(--text-muted);
  }

  .site-search-input:disabled {
    opacity: 0.6;
  }

  .site-search-clear {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    border: none;
    border-radius: 4px;
    background: none;
    color: var(--text-muted);
    cursor: pointer;
    flex-shrink: 0;
    transition: all 0.15s;
  }

  .site-search-clear:hover {
    background: var(--nav-hover-bg);
    color: var(--text-primary);
  }

  /* Scrollable site list */
  .site-list {
    max-height: 280px;
    overflow-y: auto;
    border: 1px solid var(--border-subtle);
    border-radius: 8px;
    background: var(--bg-base);
  }

  .site-list-empty {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
    color: var(--text-muted);
    font-size: 13px;
  }

  .site-list-empty p {
    margin: 0;
  }

  .site-list-group-label {
    padding: 8px 12px 4px;
    font-size: 10px;
    font-weight: 700;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    position: sticky;
    top: 0;
    background: var(--bg-base);
    z-index: 1;
  }

  .site-list-item {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 8px 12px;
    border: none;
    border-bottom: 1px solid var(--border-subtle);
    background: none;
    cursor: pointer;
    text-align: left;
    transition: background 0.12s;
    color: var(--text-primary);
  }

  .site-list-item:last-child {
    border-bottom: none;
  }

  .site-list-item:hover:not(:disabled) {
    background: var(--nav-hover-bg);
  }

  .site-list-item.selected {
    background: color-mix(in srgb, var(--input-focus-border) 10%, transparent);
  }

  .site-list-item:disabled {
    opacity: 0.5;
    cursor: not-allowed;
  }

  .site-list-item-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border-radius: 6px;
    background: color-mix(in srgb, var(--input-focus-border) 8%, transparent);
    color: var(--input-focus-border);
    flex-shrink: 0;
  }

  .site-list-item.selected .site-list-item-icon {
    background: color-mix(in srgb, var(--input-focus-border) 15%, transparent);
  }

  .site-list-item-info {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 1px;
  }

  .site-list-item-name {
    font-size: 13px;
    font-weight: 500;
    color: var(--text-primary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .site-list-item-id {
    font-size: 11px;
    color: var(--text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .site-list-item-check {
    color: var(--input-focus-border);
    flex-shrink: 0;
  }

  /* Spinner animation */
  @keyframes spin {
    to {
      transform: rotate(360deg);
    }
  }

  :global(.spin-icon) {
    animation: spin 1s linear infinite;
  }
</style>
