<script>
  import Header from '$lib/layout/Header.svelte';
  import Tables from '$lib/components/Tables.svelte';
  import ConfirmModal from '$lib/components/ui/PopUpDelete.svelte';
  import { authToken } from '$lib/utils/stores';
  import { page } from '$app/stores';
  import { onMount } from 'svelte';

  const apiUrl = import.meta.env.VITE_API_URL;

  const cprHistoryEndpoint = `${apiUrl}/cpr/history`;

  const breadcrumb = [{ label: 'Início' }, { label: 'CPR' }, { label: 'Monitoring', active: true }];

  const columns = [
    { key: 'id', label: 'ID' },
    { key: 'preview', label: 'Preview' },
    { key: 'description', label: 'Descrição' },
    { key: 'link', label: 'Link' }
  ];

  let cprOptions = [];
  let cprOptionsLoading = false;
  let cprOptionsError = '';
  let selectedCprId = '';
  let cprOptionsLoadedOnce = false;

  let requestedCprId = '';
  let requestedCprApplied = false;

  let data = [];
  let loadError = '';
  let successMessage = '';
  let isLoading = false;

  let showCreate = false;
  let createLoading = false;
  let createError = '';
  let createPreview = false;
  let createDescription = '';
  let createLink = '';

  let showEdit = false;
  let editLoading = false;
  let editError = '';
  let editId = null;
  let editPreview = false;
  let editDescription = '';
  let editLink = '';

  let showDeleteConfirm = false;
  let rowToDelete = null;
  let deleteLoading = false;
  let deleteError = '';

  function toCprOptionLabel(row) {
    const id = row?.cpr_id ?? row?.id;
    const product = row?.cpr_product_class_name ?? row?.cpr_product_name;
    const issuer = row?.cpr_issuer_name;
    const parts = [`#${id}`];
    if (product) parts.push(String(product));
    if (issuer) parts.push(String(issuer));
    return parts.join(' - ');
  }

  async function fetchCprOptions() {
    if (cprOptionsLoading) return;
    cprOptionsLoading = true;
    cprOptionsError = '';

    try {
      const token = $authToken;
      if (!token) {
        throw new Error('Sessão expirada. Faça login novamente.');
      }

      const res = await fetch(cprHistoryEndpoint, {
        method: 'POST',
        headers: {
          'content-type': 'application/json',
          Authorization: `Bearer ${token}`
        },
        body: JSON.stringify({})
      });

      const raw = await res.text();
      const body = safeParseJson(raw);

      if (!res.ok) {
        throw new Error(body?.message ?? body?.msg ?? `Falha ao carregar CPRs (HTTP ${res.status}).`);
      }

      const list = normalizeList(body);
      cprOptions = list
        .map((row) => {
          const id = Number(row?.cpr_id ?? row?.id);
          if (!Number.isInteger(id) || id <= 0) return null;
          return {
            id,
            label: toCprOptionLabel({ ...row, cpr_id: id })
          };
        })
        .filter(Boolean);

      if (!requestedCprApplied && requestedCprId) {
        const wantedId = Number(requestedCprId);
        const exists = cprOptions.some((opt) => opt.id === wantedId);
        if (exists) {
          selectedCprId = String(wantedId);
        }
        requestedCprApplied = true;
      }

      if (!selectedCprId && cprOptions.length) {
        selectedCprId = String(cprOptions[0].id);
      }
    } catch (err) {
      console.error('[CPR Monitoring] Erro ao buscar CPRs:', err);
      cprOptionsError = err?.message ?? 'Falha ao carregar CPRs.';
      cprOptions = [];
    } finally {
      cprOptionsLoading = false;
      cprOptionsLoadedOnce = true;
    }
  }

  $: if (cprOptionsLoadedOnce && !cprOptionsLoading && selectedCprId) {
    void fetchMonitoring();
  }

  function safeParseJson(raw) {
    if (!raw) return null;
    try {
      return JSON.parse(raw);
    } catch {
      return null;
    }
  }

  function normalizeList(body) {
    if (Array.isArray(body)) return body;
    if (Array.isArray(body?.data)) return body.data;
    return [];
  }

  function mapMonitoringRow(item) {
    const previewValue = item?.preview;
    const previewLabel =
      previewValue === true || previewValue === 1 || previewValue === 't' || previewValue === 'true' ? 'Sim' : 'Não';

    return {
      __raw: item,
      id: item?.id ?? '-',
      preview: previewLabel,
      description: item?.description ?? '-',
      link: item?.link ?? '-'
    };
  }

  function resolveMonitoringId(row) {
    return row?.__raw?.id ?? row?.id;
  }

  function openCreate() {
    showCreate = true;
    createError = '';
    createLoading = false;
    createPreview = false;
    createDescription = '';
    createLink = '';

    if (!cprOptions.length) {
      void fetchCprOptions();
    }
  }

  function closeCreate() {
    showCreate = false;
    createLoading = false;
    createError = '';
    createPreview = false;
    createDescription = '';
    createLink = '';
  }

  function openEditFromRow(row) {
    const raw = row?.__raw ?? row;
    const id = Number(raw?.id);
    if (!Number.isInteger(id) || id <= 0) {
      loadError = 'Registro inválido para edição.';
      return;
    }

    editId = id;
    editPreview = Boolean(raw?.preview);
    editDescription = String(raw?.description ?? '');
    editLink = String(raw?.link ?? '');
    editError = '';
    editLoading = false;
    showEdit = true;
  }

  function closeEdit() {
    showEdit = false;
    editLoading = false;
    editError = '';
    editId = null;
    editPreview = false;
    editDescription = '';
    editLink = '';
  }

  async function fetchMonitoring() {
    if (isLoading) return;

    const cprId = Number(selectedCprId);
    if (!Number.isInteger(cprId) || cprId <= 0) {
      loadError = 'Selecione uma CPR válida para listar.';
      data = [];
      return;
    }

    isLoading = true;
    loadError = '';
    try {
      const token = $authToken;
      if (!token) {
        throw new Error('Sessão expirada. Faça login novamente.');
      }

      const res = await fetch(`${apiUrl}/cpr/monitoring/list`, {
        method: 'POST',
        headers: {
          'content-type': 'application/json',
          Authorization: `Bearer ${token}`
        },
        body: JSON.stringify({ cpr_id: cprId })
      });

      if (res.status === 204) {
        data = [];
        return;
      }

      const raw = await res.text();
      const body = safeParseJson(raw);

      if (!res.ok || body?.status !== 'ok') {
        throw new Error(body?.msg ?? body?.message ?? `Falha ao carregar registros (HTTP ${res.status}).`);
      }

      const list = normalizeList(body);
      data = list.map(mapMonitoringRow);
    } catch (err) {
      console.error('[CPR Monitoring] Erro ao buscar registros:', err);
      loadError = err?.message ?? 'Falha ao carregar registros.';
      data = [];
    } finally {
      isLoading = false;
    }
  }

  function handleEditRow(e) {
    const { row } = e?.detail || {};
    if (!row) return;
    openEditFromRow(row);
  }

  function handleDeleteRow(e) {
    const { row } = e?.detail || {};
    if (!row) return;
    rowToDelete = row;
    deleteError = '';
    deleteLoading = false;
    showDeleteConfirm = true;
  }

  async function handleCreateSubmit() {
    if (createLoading) return;
    createError = '';

    const cprId = Number(selectedCprId);
    if (!Number.isInteger(cprId) || cprId <= 0) {
      createError = 'Selecione uma CPR válida.';
      return;
    }

    const description = String(createDescription ?? '').trim();
    if (!description || description.length > 5000) {
      createError = 'Informe uma descrição válida (1 a 5000 caracteres).';
      return;
    }

    const link = String(createLink ?? '').trim();
    if (!link || link.length > 2048) {
      createError = 'Informe um link válido (1 a 2048 caracteres).';
      return;
    }

    const token = $authToken;
    if (!token) {
      createError = 'Sessão expirada. Faça login novamente.';
      return;
    }

    createLoading = true;
    try {
      const createPayload = {
        cpr_id: cprId,
        preview: createPreview === true,
        description,
        link
      };

      const res = await fetch(`${apiUrl}/cpr/monitoring/create`, {
        method: 'POST',
        headers: {
          'content-type': 'application/json',
          Authorization: `Bearer ${token}`
        },
        body: JSON.stringify(createPayload)
      });

      const raw = await res.text();
      const body = safeParseJson(raw);

      const isSuccess = res.ok && body?.status === 'ok' && body?.code === 'S_CREATED' && body?.data?.id != null;
      if (!isSuccess) {
        throw new Error(body?.msg ?? body?.message ?? `Falha ao criar registro (HTTP ${res.status}).`);
      }

      successMessage = body?.msg ?? body?.message ?? 'Registro criado com sucesso!';
      closeCreate();
      await fetchMonitoring();
    } catch (err) {
      console.error('[CPR Monitoring] Erro ao criar registro:', err);
      createError = err?.message ?? 'Falha ao criar registro.';
    } finally {
      createLoading = false;
    }
  }

  async function handleEditSubmit() {
    if (editLoading) return;
    editError = '';

    const id = Number(editId);
    if (!Number.isInteger(id) || id <= 0) {
      editError = 'ID inválido.';
      return;
    }

    const description = String(editDescription ?? '').trim();
    if (!description || description.length > 5000) {
      editError = 'Informe uma descrição válida (1 a 5000 caracteres).';
      return;
    }

    const link = String(editLink ?? '').trim();
    if (!link || link.length > 2048) {
      editError = 'Informe um link válido (1 a 2048 caracteres).';
      return;
    }

    const token = $authToken;
    if (!token) {
      editError = 'Sessão expirada. Faça login novamente.';
      return;
    }

    editLoading = true;
    try {
      const editPayload = {
        id,
        preview: editPreview === true,
        description,
        link
      };

      const res = await fetch(`${apiUrl}/cpr/monitoring/update`, {
        method: 'POST',
        headers: {
          'content-type': 'application/json',
          Authorization: `Bearer ${token}`
        },
        body: JSON.stringify(editPayload)
      });

      if (res.status === 204) {
        throw new Error('Registro não encontrado ou não atualizado.');
      }

      const raw = await res.text();
      const body = safeParseJson(raw);

      const isSuccess = res.ok && body?.status === 'ok' && body?.code === 'S_UPDATED' && body?.data?.id != null;
      if (!isSuccess) {
        throw new Error(body?.msg ?? body?.message ?? `Falha ao atualizar registro (HTTP ${res.status}).`);
      }

      successMessage = body?.msg ?? body?.message ?? 'Registro atualizado com sucesso!';
      closeEdit();
      await fetchMonitoring();
    } catch (err) {
      console.error('[CPR Monitoring] Erro ao atualizar registro:', err);
      editError = err?.message ?? 'Falha ao atualizar registro.';
    } finally {
      editLoading = false;
    }
  }

  async function confirmDelete() {
    if (deleteLoading) return;
    deleteError = '';

    const idRaw = resolveMonitoringId(rowToDelete);
    const id = Number(idRaw);
    if (!Number.isInteger(id) || id <= 0) {
      deleteError = 'ID inválido para exclusão.';
      return;
    }

    const token = $authToken;
    if (!token) {
      deleteError = 'Sessão expirada. Faça login novamente.';
      return;
    }

    deleteLoading = true;
    let deleted = false;

    try {
      const res = await fetch(`${apiUrl}/cpr/monitoring/delete`, {
        method: 'POST',
        headers: {
          'content-type': 'application/json',
          Authorization: `Bearer ${token}`
        },
        body: JSON.stringify({ id })
      });

      if (res.status === 204) {
        throw new Error('Registro não encontrado.');
      }

      const raw = await res.text();
      const body = safeParseJson(raw);

      const isSuccess = res.ok && body?.status === 'ok' && body?.code === 'S_DELETED' && body?.data?.deleted === true;
      if (!isSuccess) {
        throw new Error(body?.msg ?? body?.message ?? `Falha ao excluir registro (HTTP ${res.status}).`);
      }

      deleted = true;
      successMessage = body?.msg ?? body?.message ?? 'Registro excluído com sucesso!';
      await fetchMonitoring();
    } catch (err) {
      console.error('[CPR Monitoring] Erro ao excluir registro:', err);
      deleteError = err?.message ?? 'Falha ao excluir registro.';
    } finally {
      deleteLoading = false;
      if (deleted) {
        showDeleteConfirm = false;
        rowToDelete = null;
      }
    }
  }

  function cancelDelete() {
    showDeleteConfirm = false;
    rowToDelete = null;
    deleteError = '';
    deleteLoading = false;
  }

  onMount(() => {
    loadError = '';
    requestedCprId = String($page.url.searchParams.get('cpr_id') ?? '');
    requestedCprApplied = false;
    void fetchCprOptions();
  });
</script>

<div>
  <Header title="CPR - Monitoring" subtitle="Gestão de registros de monitoramento por CPR" breadcrumb={breadcrumb} />

  <div class="p-4">
    <div class="max-w-6xl mx-auto mt-4">
      {#if loadError}
        <div class="mb-4 rounded border border-red-300 bg-red-50 text-red-700 px-3 py-2 text-sm dark:border-red-700 dark:bg-red-900/30 dark:text-red-200">{loadError}</div>
      {/if}

      {#if successMessage}
        <div class="mb-4 rounded border border-green-300 bg-green-50 text-green-700 px-3 py-2 text-sm dark:border-green-700 dark:bg-green-900/20 dark:text-green-200">
          {successMessage}
        </div>
      {/if}

      <section class="space-y-4">
        <div class="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
          <div>
            <h2 class="text-lg font-semibold text-gray-900 dark:text-gray-50">Registros de monitoramento</h2>
            <p class="text-sm text-gray-500 dark:text-gray-400">Liste, crie, edite ou remova registros vinculados a uma CPR.</p>
          </div>

          <div class="flex flex-col gap-2 sm:flex-row sm:items-center">
            <select
              class="min-w-64 rounded border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700/70 text-gray-900 dark:text-gray-100 px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500 disabled:opacity-60"
              bind:value={selectedCprId}
              disabled={isLoading || cprOptionsLoading}
            >
              <option value="" disabled>Selecione uma CPR</option>
              {#each cprOptions as opt}
                <option value={String(opt.id)}>{opt.label}</option>
              {/each}
            </select>

            {#if cprOptionsError}
              <div class="text-xs text-red-600 dark:text-red-400">{cprOptionsError}</div>
            {/if}

            <button
              type="button"
              class="inline-flex items-center gap-2 rounded-md border border-gray-300 dark:border-gray-600 px-4 py-2 text-sm font-medium text-gray-700 dark:text-gray-100 hover:bg-gray-100 dark:hover:bg-gray-700 disabled:opacity-60"
              on:click={fetchMonitoring}
              disabled={isLoading}
            >
              {isLoading ? 'Atualizando...' : 'Atualizar'}
            </button>

            <button
              type="button"
              class="inline-flex items-center gap-2 rounded-md border border-gray-300 dark:border-gray-600 px-4 py-2 text-sm font-medium text-gray-700 dark:text-gray-100 hover:bg-gray-100 dark:hover:bg-gray-700 disabled:opacity-60"
              on:click={openCreate}
              disabled={isLoading}
            >
              Novo registro
            </button>
          </div>
        </div>

        <Tables
          title="Registros"
          {columns}
          {data}
          on:editRow={handleEditRow}
          on:deleteRow={handleDeleteRow}
          showAdd={false}
        />
      </section>

      {#if showCreate}
        <div
          class="fixed inset-0 bg-black/40 flex items-center justify-center z-50"
          role="button"
          tabindex="0"
          on:click={(e) => {
            if (e.target === e.currentTarget && !createLoading) closeCreate();
          }}
          on:keydown={(e) => {
            if (e.key === 'Escape' && !createLoading) closeCreate();
          }}
        >
          <div
            class="bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg shadow-lg w-full max-w-2xl p-6"
            role="dialog"
            aria-modal="true"
            on:keydown|stopPropagation
          >
            <div class="flex items-center justify-between mb-4">
              <h4 class="text-lg font-semibold text-gray-900 dark:text-gray-100">Criar registro</h4>
              <button type="button" class="text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200" on:click={() => (!createLoading ? closeCreate() : null)}>✕</button>
            </div>

            <div class="space-y-4">
              <div>
                <label class="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">CPR</label>
                <select
                  class="w-full rounded border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-900 px-3 py-2 text-sm text-gray-800 dark:text-gray-100 disabled:opacity-60"
                  bind:value={selectedCprId}
                  disabled={createLoading || cprOptionsLoading}
                >
                  <option value="" disabled>Selecione uma CPR</option>
                  {#each cprOptions as opt}
                    <option value={String(opt.id)}>{opt.label}</option>
                  {/each}
                </select>
                {#if cprOptionsError}
                  <div class="mt-1 text-xs text-red-600 dark:text-red-400">{cprOptionsError}</div>
                {/if}
              </div>

              <div class="flex items-center gap-2">
                <input id="create-preview" type="checkbox" bind:checked={createPreview} disabled={createLoading} />
                <label for="create-preview" class="text-sm text-gray-700 dark:text-gray-200">Preview</label>
              </div>

              <div>
                <label class="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">Descrição</label>
                <textarea
                  class="w-full rounded border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-900 px-3 py-2 text-sm text-gray-800 dark:text-gray-100"
                  rows="6"
                  maxlength="5000"
                  bind:value={createDescription}
                  disabled={createLoading}
                ></textarea>
              </div>

              <div>
                <label class="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">Link</label>
                <input
                  class="w-full rounded border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-900 px-3 py-2 text-sm text-gray-800 dark:text-gray-100"
                  type="text"
                  maxlength="2048"
                  bind:value={createLink}
                  disabled={createLoading}
                />
              </div>

              {#if createError}
                <div class="rounded border border-red-200 dark:border-red-700 bg-red-50 dark:bg-red-900/30 text-red-700 dark:text-red-200 px-3 py-2 text-sm">
                  {createError}
                </div>
              {/if}

              <div class="grid grid-cols-1 md:grid-cols-2 gap-2 pt-2">
                <button
                  type="button"
                  class="rounded border border-gray-300 dark:border-gray-600 py-2 text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-700 disabled:opacity-60"
                  on:click={closeCreate}
                  disabled={createLoading}
                >
                  Cancelar
                </button>
                <button
                  type="button"
                  class="rounded bg-blue-600 hover:bg-blue-700 text-white font-semibold py-2 disabled:opacity-60"
                  on:click={handleCreateSubmit}
                  disabled={createLoading}
                >
                  {createLoading ? 'Criando...' : 'Criar'}
                </button>
              </div>
            </div>
          </div>
        </div>
      {/if}

      {#if showEdit}
        <div
          class="fixed inset-0 bg-black/40 flex items-center justify-center z-50"
          role="button"
          tabindex="0"
          on:click={(e) => {
            if (e.target === e.currentTarget && !editLoading) closeEdit();
          }}
          on:keydown={(e) => {
            if (e.key === 'Escape' && !editLoading) closeEdit();
          }}
        >
          <div
            class="bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg shadow-lg w-full max-w-2xl p-6"
            role="dialog"
            aria-modal="true"
            on:keydown|stopPropagation
          >
            <div class="flex items-center justify-between mb-4">
              <h4 class="text-lg font-semibold text-gray-900 dark:text-gray-100">Editar registro #{editId}</h4>
              <button type="button" class="text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200" on:click={() => (!editLoading ? closeEdit() : null)}>✕</button>
            </div>

            <div class="space-y-4">
              <div class="flex items-center gap-2">
                <input id="edit-preview" type="checkbox" bind:checked={editPreview} disabled={editLoading} />
                <label for="edit-preview" class="text-sm text-gray-700 dark:text-gray-200">Preview</label>
              </div>

              <div>
                <label class="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">Descrição</label>
                <textarea
                  class="w-full rounded border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-900 px-3 py-2 text-sm text-gray-800 dark:text-gray-100"
                  rows="6"
                  maxlength="5000"
                  bind:value={editDescription}
                  disabled={editLoading}
                ></textarea>
              </div>

              <div>
                <label class="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">Link</label>
                <input
                  class="w-full rounded border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-900 px-3 py-2 text-sm text-gray-800 dark:text-gray-100"
                  type="text"
                  maxlength="2048"
                  bind:value={editLink}
                  disabled={editLoading}
                />
              </div>

              {#if editError}
                <div class="rounded border border-red-200 dark:border-red-700 bg-red-50 dark:bg-red-900/30 text-red-700 dark:text-red-200 px-3 py-2 text-sm">
                  {editError}
                </div>
              {/if}

              <div class="grid grid-cols-1 md:grid-cols-2 gap-2 pt-2">
                <button
                  type="button"
                  class="rounded border border-gray-300 dark:border-gray-600 py-2 text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-700 disabled:opacity-60"
                  on:click={closeEdit}
                  disabled={editLoading}
                >
                  Cancelar
                </button>
                <button
                  type="button"
                  class="rounded bg-blue-600 hover:bg-blue-700 text-white font-semibold py-2 disabled:opacity-60"
                  on:click={handleEditSubmit}
                  disabled={editLoading}
                >
                  {editLoading ? 'Salvando...' : 'Salvar'}
                </button>
              </div>
            </div>
          </div>
        </div>
      {/if}

      <ConfirmModal
        visible={showDeleteConfirm}
        title="Confirmar exclusão"
        confirmText={deleteLoading ? 'Excluindo...' : 'Excluir'}
        cancelText="Cancelar"
        disableBackdropClose={deleteLoading}
        confirmDisabled={deleteLoading}
        on:confirm={confirmDelete}
        on:cancel={cancelDelete}
      >
        <p>Tem certeza que deseja excluir o registro "{rowToDelete?.id}"?</p>
        {#if deleteError}
          <p class="mt-3 text-sm text-red-600 dark:text-red-400">{deleteError}</p>
        {/if}
      </ConfirmModal>
    </div>
  </div>
</div>
