<script lang="ts">
  import { onMount } from "svelte";
  import * as db from "$lib/db";
  import { daysInMonth, isoDate, MONTH_NAMES } from "$lib/dates";
  import { formatMoney } from "$lib/money";
  import type { Cabin, CabinReport, RevenueStats } from "$lib/types";

  let year = $state(new Date().getFullYear());
  let cabins = $state<Cabin[]>([]);
  let yearStats = $state<RevenueStats | null>(null);
  let cabinRows = $state<CabinReport[]>([]);
  let monthRows = $state<RevenueStats[]>([]);
  let loading = $state(true);
  let error = $state<string | null>(null);

  let isLeap = $derived(new Date(year, 1, 29).getDate() === 29);
  let daysInYear = $derived(isLeap ? 366 : 365);

  async function reload() {
    loading = true;
    error = null;
    try {
      const from = isoDate(year, 0, 1);
      const to = isoDate(year + 1, 0, 1);
      const monthRanges = Array.from({ length: 12 }, (_, m) => ({
        from: isoDate(year, m, 1),
        to: m === 11 ? isoDate(year + 1, 0, 1) : isoDate(year, m + 1, 1)
      }));
      const [c, ys, cr, ...months] = await Promise.all([
        db.listCabins(),
        db.revenueStats(from, to),
        db.cabinReports(from, to),
        ...monthRanges.map((r) => db.revenueStats(r.from, r.to))
      ]);
      cabins = c;
      yearStats = ys;
      cabinRows = cr;
      monthRows = months;
    } catch (e) {
      error = `Nie udało się wczytać raportu: ${e}`;
    } finally {
      loading = false;
    }
  }

  onMount(() => {
    void reload();
  });

  function changeYear(delta: number) {
    year += delta;
    void reload();
  }

  function cabinName(id: number): string {
    return cabins.find((c) => c.id === id)?.name ?? `Domek #${id}`;
  }

  function occupancy(nights: number, availableNights: number): string {
    if (availableNights <= 0) return "—";
    return `${Math.round((nights / availableNights) * 100)}%`;
  }

  let maxMonthRevenue = $derived(Math.max(1, ...monthRows.map((m) => m.revenue_total)));
</script>

<svelte:head>
  <title>Słoneczko — raporty</title>
</svelte:head>

<main>
  <header class="toolbar">
    <h1>Raporty</h1>
    <span class="spacer"></span>
    <button type="button" class="icon" onclick={() => changeYear(-1)} aria-label="Poprzedni rok">‹</button>
    <span class="year">{year}</span>
    <button type="button" class="icon" onclick={() => changeYear(1)} aria-label="Następny rok">›</button>
  </header>

  {#if error}
    <p class="error">{error}</p>
  {:else if yearStats}
    <div class="cards">
      <div class="card">
        <span class="label">Doby (wszystkie)</span>
        <span class="value">{Math.round(yearStats.nights_total)}</span>
      </div>
      <div class="card">
        <span class="label">Obłożenie</span>
        <span class="value">{occupancy(yearStats.nights_total, cabins.length * daysInYear)}</span>
      </div>
      <div class="card">
        <span class="label">Przychód potencjalny</span>
        <span class="value">{formatMoney(yearStats.revenue_total)} zł</span>
      </div>
      <div class="card">
        <span class="label">Przychód potwierdzony</span>
        <span class="value">{formatMoney(yearStats.revenue_confirmed)} zł</span>
      </div>
    </div>

    <section>
      <h2>Przychód miesięczny</h2>
      <div class="chart">
        {#each monthRows as m, i (i)}
          <div class="col">
            <span class="amount">{m.revenue_total > 0 ? formatMoney(m.revenue_total) : ""}</span>
            <div class="barwrap">
              <div
                class="bar"
                style="height: {(m.revenue_total / maxMonthRevenue) * 100}%"
                title="{MONTH_NAMES[i]}: {formatMoney(m.revenue_total)} zł (potwierdzone {formatMoney(m.revenue_confirmed)} zł)"
              >
                <div
                  class="bar confirmed-part"
                  style="height: {m.revenue_total > 0 ? (m.revenue_confirmed / m.revenue_total) * 100 : 0}%"
                ></div>
              </div>
            </div>
            <span class="m">{MONTH_NAMES[i].slice(0, 3)}</span>
          </div>
        {/each}
      </div>
      <p class="hint">Ciemniejsza część słupka to przychód z rezerwacji potwierdzonych.</p>
    </section>

    <div class="two-cols">
      <section>
        <h2>Wg domków</h2>
        <table>
          <thead>
            <tr>
              <th>Domek</th>
              <th class="num">Doby</th>
              <th class="num">Obłożenie</th>
              <th class="num">Przychód</th>
            </tr>
          </thead>
          <tbody>
            {#each cabins as cabin (cabin.id)}
              {@const row = cabinRows.find((r) => r.cabin_id === cabin.id)}
              <tr>
                <td>{cabin.name}</td>
                <td class="num">{row ? Math.round(row.nights_total) : 0}</td>
                <td class="num">{occupancy(row?.nights_total ?? 0, daysInYear)}</td>
                <td class="num">{formatMoney(row?.revenue_total ?? 0)} zł</td>
              </tr>
            {/each}
          </tbody>
        </table>
      </section>

      <section>
        <h2>Wg miesięcy</h2>
        <table>
          <thead>
            <tr>
              <th>Miesiąc</th>
              <th class="num">Doby</th>
              <th class="num">Obłożenie</th>
              <th class="num">Przychód</th>
            </tr>
          </thead>
          <tbody>
            {#each monthRows as m, i (i)}
              <tr>
                <td>{MONTH_NAMES[i]}</td>
                <td class="num">{Math.round(m.nights_total)}</td>
                <td class="num">{occupancy(m.nights_total, cabins.length * daysInMonth(year, i))}</td>
                <td class="num">{formatMoney(m.revenue_total)} zł</td>
              </tr>
            {/each}
          </tbody>
        </table>
      </section>
    </div>
  {:else if loading}
    <p class="hint">Wczytywanie…</p>
  {/if}
</main>

<style>
  main {
    padding: 14px 16px;
    max-width: 980px;
  }
  .toolbar {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 14px;
  }
  h1 {
    margin: 0;
    font-size: 18px;
  }
  .spacer {
    flex: 1;
  }
  .year {
    min-width: 60px;
    text-align: center;
    font-size: 16px;
    font-weight: 600;
  }
  .toolbar button.icon {
    font: inherit;
    width: 34px;
    padding: 7px 0;
    font-size: 16px;
    line-height: 1;
    border-radius: 7px;
    border: 1px solid var(--border);
    background: var(--surface);
    color: var(--text);
    cursor: pointer;
  }
  .error {
    color: var(--danger);
  }
  .hint {
    color: var(--muted);
    font-size: 12px;
    margin: 8px 0 0;
  }
  .cards {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 10px;
    margin-bottom: 14px;
  }
  .card {
    display: flex;
    flex-direction: column;
    gap: 4px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 12px 14px;
  }
  .card .label {
    font-size: 11px;
    color: var(--muted);
  }
  .card .value {
    font-size: 20px;
    font-weight: 600;
  }
  section {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 14px 16px;
    margin-bottom: 14px;
  }
  h2 {
    margin: 0 0 12px;
    font-size: 14px;
  }
  .chart {
    display: flex;
    gap: 8px;
    align-items: stretch;
    height: 180px;
  }
  .col {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    min-width: 0;
  }
  .amount {
    font-size: 10px;
    color: var(--muted);
    white-space: nowrap;
    overflow: hidden;
    max-width: 100%;
  }
  .barwrap {
    flex: 1;
    width: 100%;
    display: flex;
    align-items: flex-end;
  }
  .chart .bar {
    width: 100%;
    background: var(--bar-confirmed-bg);
    border-radius: 4px 4px 0 0;
    position: relative;
    display: flex;
    align-items: flex-end;
  }
  .chart .bar .confirmed-part {
    background: var(--accent);
    border-radius: 0;
  }
  .m {
    font-size: 11px;
    color: var(--muted);
  }
  .two-cols {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 14px;
    align-items: start;
  }
  table {
    width: 100%;
    border-collapse: collapse;
  }
  th,
  td {
    padding: 6px 8px;
    text-align: left;
    font-size: 13px;
    border-top: 1px solid var(--border);
  }
  thead th {
    border-top: none;
    font-size: 11px;
    color: var(--muted);
    font-weight: 600;
  }
  .num {
    text-align: right;
  }
</style>
