'use client';

import { useState } from 'react';
import type { StoreSite } from '@alqove/api-client';
import { DesignPanel } from './design-panel';
import { DetailsPanel } from './details-panel';
import { DomainsPanel } from './domains-panel';
import { PagesPanel } from './pages-panel';
import { PreviewPanel } from './preview-panel';
import { pageRevision, toDraft, type PageDraft } from './page-draft';
import { firstError, useSiteMutations, useStoreId, useStoreSite } from './use-store-site';
import { ErrorText, inputCls, Panel, PrimaryButton, SecondaryButton } from './ui';

const TABS = [
  { id: 'pages', label: 'Pages' },
  { id: 'design', label: 'Design' },
  { id: 'details', label: 'Details' },
  { id: 'domains', label: 'Domain' },
] as const;

type TabId = (typeof TABS)[number]['id'];

export default function SitePage() {
  const storeId = useStoreId();
  const siteQ = useStoreSite(storeId);
  const [tab, setTab] = useState<TabId>('pages');
  const [selectedPageId, setSelectedPageId] = useState<string | null>(null);
  const [draft, setDraft] = useState<PageDraft | null>(null);
  const [draftRevision, setDraftRevision] = useState<string | null>(null);

  if (!storeId) {
    return <p className="text-sm text-ink/60">You need a store before you can build a website.</p>;
  }

  if (siteQ.isLoading) return <p className="text-sm text-ink/60">Loading…</p>;

  const site = siteQ.data?.data as StoreSite | undefined;

  if (!site) {
    return (
      <ErrorText>{firstError(siteQ.error) ?? 'We could not load your website settings.'}</ErrorText>
    );
  }

  const pages = site.pages ?? [];
  const selected = pages.find((p) => p.id === selectedPageId) ?? pages[0] ?? null;
  const revision = pageRevision(selected);

  // Derive the draft during render rather than in an effect: this fires when
  // the seller switches pages, and again after a save (whose new `updated_at`
  // changes the revision) so the editor adopts the server's normalised slugs
  // and freshly-assigned block ids.
  if (revision && revision !== draftRevision && selected) {
    setDraftRevision(revision);
    setDraft(toDraft(selected));
  }

  const patchDraft = (patch: Partial<PageDraft>) =>
    setDraft((current) => (current ? { ...current, ...patch } : current));

  return (
    <div className="space-y-6">
      <PublishBar storeId={storeId} site={site} />

      <nav className="flex gap-1 border-b border-forest/15" aria-label="Website sections">
        {TABS.map((t) => (
          <button
            key={t.id}
            type="button"
            onClick={() => setTab(t.id)}
            aria-current={tab === t.id ? 'page' : undefined}
            className={`-mb-px border-b-2 px-4 py-2 text-sm font-medium ${
              tab === t.id
                ? 'border-forest text-forest'
                : 'border-transparent text-ink/60 hover:text-ink'
            }`}
          >
            {t.label}
          </button>
        ))}
      </nav>

      <div className="grid gap-6 xl:grid-cols-[minmax(0,1fr)_minmax(0,26rem)]">
        <div className="min-w-0 space-y-6">
          {tab === 'pages' && (
            <PagesPanel
              storeId={storeId}
              pages={pages}
              selected={selected}
              draft={draft}
              onDraftChange={patchDraft}
              onSelectPage={setSelectedPageId}
            />
          )}
          {tab === 'design' && <DesignPanel storeId={storeId} site={site} />}
          {tab === 'details' && <DetailsPanel storeId={storeId} site={site} />}
          {tab === 'domains' && <DomainsPanel storeId={storeId} site={site} />}
        </div>

        <div className="min-w-0">
          <div className="xl:sticky xl:top-6">
            <PreviewPanel storeId={storeId} site={site} blocks={draft?.blocks ?? []} />
          </div>
        </div>
      </div>
    </div>
  );
}

function PublishBar({ storeId, site }: { storeId: string; site: StoreSite }) {
  const { updateSite, updateSlug } = useSiteMutations(storeId);
  const [editingSlug, setEditingSlug] = useState(false);
  const [slug, setSlug] = useState(site.store_slug ?? '');

  const published = site.is_published ?? false;

  return (
    <Panel
      title="Your website"
      description={
        published
          ? 'Live and visible to anyone with the link.'
          : 'Not published yet — only you can see it.'
      }
      actions={
        <div className="flex items-center gap-2">
          {published && site.public_url && (
            <a
              href={site.public_url}
              target="_blank"
              rel="noopener noreferrer"
              className="rounded border border-forest/20 px-3 py-1.5 text-sm hover:bg-bone"
            >
              Visit site
            </a>
          )}
          <PrimaryButton
            onClick={() => updateSite.mutate({ is_published: !published })}
            disabled={updateSite.isPending}
          >
            {updateSite.isPending ? 'Saving…' : published ? 'Unpublish' : 'Publish'}
          </PrimaryButton>
        </div>
      }
    >
      <div className="flex flex-wrap items-end gap-3">
        {editingSlug ? (
          <>
            <label className="flex flex-1 flex-col gap-1 text-sm">
              <span className="text-xs uppercase tracking-wide text-ink/60">Address</span>
              <input
                className={inputCls}
                value={slug}
                onChange={(e) => setSlug(e.target.value)}
                aria-label="Storefront address"
              />
            </label>
            <PrimaryButton
              onClick={() =>
                updateSlug.mutate(slug.trim(), { onSuccess: () => setEditingSlug(false) })
              }
              disabled={updateSlug.isPending}
            >
              {updateSlug.isPending ? 'Saving…' : 'Save address'}
            </PrimaryButton>
            <SecondaryButton
              onClick={() => {
                setSlug(site.store_slug ?? '');
                setEditingSlug(false);
              }}
            >
              Cancel
            </SecondaryButton>
          </>
        ) : (
          <>
            <p className="flex-1 break-all font-mono text-sm text-ink/70">{site.public_url}</p>
            <SecondaryButton onClick={() => setEditingSlug(true)}>Change address</SecondaryButton>
          </>
        )}
      </div>
      {/* Changing the address breaks existing links — worth saying out loud. */}
      {editingSlug && (
        <p className="mt-2 text-xs text-ink/50">
          Any links already pointing at the old address will stop working.
        </p>
      )}
      <ErrorText>{firstError(updateSlug.error) ?? firstError(updateSite.error)}</ErrorText>
    </Panel>
  );
}
