"use client";

import { useEffect, useMemo, useState } from 'react';
import { AdminShell } from '../components/admin/admin-page.jsx';

async function api(path, options) {
  const res = await fetch(path, options);
  if (!res.ok) throw new Error(await res.text());
  return res.json();
}

function listText(values) {
  return (values || []).join('\n');
}

function colorText(colors) {
  return (colors || []).map(c => `${c.name || 'Color'}: ${c.value}`).join('\n');
}

function syncedLabel(iso) {
  if (!iso) return '';
  const d = new Date(iso);
  if (Number.isNaN(d.getTime())) return '';
  return d.toLocaleString([], { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' });
}

// Team-sharing panel. Local-first by default; an owner/admin can publish the
// brand to the org and any member can adopt the shared org brand locally.
function ShareCard({ share, sharing, onShare }) {
  const ready = share?.shared_cloud_ready;
  const status = share?.status || {};
  const canManage = Boolean(share?.can_manage);
  const orgBrand = share?.org_brand || null;
  const busy = Boolean(sharing);

  const state = !ready ? 'Local only'
    : status.source === 'org' || status.status === 'adopted' ? 'Using team brand'
      : status.published ? 'Shared with team'
        : 'Saved locally';

  return (
    <section className="brand-panel brand-share-panel">
      <div className="brand-panel-head">
        <span>Team Sharing</span>
        <small>{ready ? 'Save locally, or share one brand across your org' : 'Supabase not configured'}</small>
      </div>

      <div className="brand-share-state">
        <span className={`brand-share-chip ${status.published ? 'on' : status.source === 'org' ? 'org' : ''}`}>{state}</span>
        {ready && status.published && status.last_synced_at && (
          <small>Synced {syncedLabel(status.last_synced_at)}</small>
        )}
        {ready && status.source === 'org' && status.adopted_at && (
          <small>Adopted {syncedLabel(status.adopted_at)}</small>
        )}
      </div>

      {!ready ? (
        <p className="brand-share-hint">
          Your brand is stored locally on this machine. To share one brand across your team,
          configure Supabase (SUPABASE_URL + service-role key) and create an organization.
        </p>
      ) : (
        <>
          {share?.needs_org && (
            <p className="brand-share-hint">Join or create an organization to share your brand with a team.</p>
          )}

          {orgBrand && !orgBrand.is_current && (
            <div className="brand-share-row">
              <div>
                <b>Team brand available</b>
                <small>{orgBrand.company_name}{orgBrand.updated_at ? ` · updated ${syncedLabel(orgBrand.updated_at)}` : ''}</small>
              </div>
              <button type="button" className="admin-button" disabled={busy} onClick={() => onShare('adopt')}>
                {sharing === 'adopt' ? 'Adopting…' : 'Adopt team brand'}
              </button>
            </div>
          )}
          {orgBrand && orgBrand.is_current && (
            <p className="brand-share-hint">This workspace matches the team brand.</p>
          )}

          {canManage ? (
            <div className="brand-share-actions">
              <button type="button" className="admin-button mars" disabled={busy} onClick={() => onShare('publish')}>
                {sharing === 'publish' ? 'Sharing…' : status.published ? 'Update shared brand' : 'Share with team'}
              </button>
              {status.published && (
                <button type="button" className="admin-button" disabled={busy} onClick={() => onShare('unpublish')}>
                  {sharing === 'unpublish' ? 'Stopping…' : 'Stop sharing'}
                </button>
              )}
            </div>
          ) : (
            <p className="brand-share-hint">Only org owners and admins can publish the team brand.</p>
          )}
        </>
      )}
    </section>
  );
}

export default function BrandPage() {
  const [brand, setBrand] = useState(null);
  const [draft, setDraft] = useState(null);
  const [saving, setSaving] = useState(false);
  const [uploading, setUploading] = useState(null);
  const [notice, setNotice] = useState(null);
  const [share, setShare] = useState(null);
  const [sharing, setSharing] = useState(null);

  async function refresh() {
    const data = await api('/api/brand');
    setBrand(data.brand);
    setDraft({
      ...data.brand,
      colors_text: colorText(data.brand.colors),
      fonts_text: listText(data.brand.fonts),
      voice_text: listText(data.brand.voice),
      document_types_text: listText(data.brand.document_types),
    });
  }

  async function refreshShare() {
    try {
      const data = await api('/api/brand/share');
      setShare(data);
    } catch {
      // Sharing is optional surface; never block the editor on it.
      setShare({ ok: false, shared_cloud_ready: false });
    }
  }

  useEffect(() => {
    refresh().catch(err => setNotice({ type: 'error', text: err.message }));
    refreshShare();
  }, []);

  useEffect(() => {
    if (!notice || notice.type !== 'success') return;
    const timer = setTimeout(() => setNotice(null), 4200);
    return () => clearTimeout(timer);
  }, [notice]);

  const accent = useMemo(() => {
    return draft?.colors?.find(c => c.value)?.value || '#C2452A';
  }, [draft]);

  function update(key, value) {
    setDraft(prev => ({ ...prev, [key]: value }));
  }

  async function save() {
    setSaving(true);
    setNotice(null);
    try {
      const body = {
        active: draft.active,
        company_name: draft.company_name,
        tagline: draft.tagline,
        presentation_style: draft.presentation_style,
        colors: draft.colors_text,
        fonts: draft.fonts_text,
        voice: draft.voice_text,
        document_types: draft.document_types_text,
      };
      const data = await api('/api/brand', {
        method: 'PUT',
        headers: { 'content-type': 'application/json' },
        body: JSON.stringify(body),
      });
      setBrand(data.brand);
      setDraft({
        ...data.brand,
        colors_text: colorText(data.brand.colors),
        fonts_text: listText(data.brand.fonts),
        voice_text: listText(data.brand.voice),
        document_types_text: listText(data.brand.document_types),
      });
      const savedAt = new Date().toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
      setNotice({ type: 'success', text: `Brand defaults saved at ${savedAt}. Future artifacts will use this profile.` });
    } catch (err) {
      setNotice({ type: 'error', text: err.message });
    } finally {
      setSaving(false);
    }
  }

  async function upload(kind, file) {
    if (!file) return;
    setUploading(kind);
    setNotice(null);
    try {
      const form = new FormData();
      form.set('kind', kind);
      form.set('file', file);
      const data = await api('/api/brand', { method: 'POST', body: form });
      setBrand(data.brand);
      setDraft({
        ...data.brand,
        colors_text: colorText(data.brand.colors),
        fonts_text: listText(data.brand.fonts),
        voice_text: listText(data.brand.voice),
        document_types_text: listText(data.brand.document_types),
      });
      setNotice({
        type: 'success',
        text: kind === 'logo' ? 'Logo updated. Future branded artifacts will use it.' : 'Guidelines imported and extracted. Brand defaults are active.',
      });
    } catch (err) {
      setNotice({ type: 'error', text: err.message });
    } finally {
      setUploading(null);
    }
  }

  async function doShare(action) {
    setSharing(action);
    setNotice(null);
    try {
      const data = await api('/api/brand/share', {
        method: 'POST',
        headers: { 'content-type': 'application/json' },
        body: JSON.stringify({ action }),
      });
      // Adopt replaces the local brand — re-pull the editor so it reflects the org brand.
      if (action === 'adopt' && data.brand) {
        setBrand(data.brand);
        setDraft({
          ...data.brand,
          colors_text: colorText(data.brand.colors),
          fonts_text: listText(data.brand.fonts),
          voice_text: listText(data.brand.voice),
          document_types_text: listText(data.brand.document_types),
        });
      }
      await refreshShare();
      const msg = action === 'publish' ? 'Brand shared with your team. Members can now adopt it.'
        : action === 'unpublish' ? 'Stopped sharing. Your brand stays saved locally.'
          : 'Adopted your team brand. It is now this workspace’s default.';
      setNotice({ type: 'success', text: msg });
    } catch (err) {
      setNotice({ type: 'error', text: err.message });
    } finally {
      setSharing(null);
    }
  }

  if (!draft) {
    return (
      <AdminShell
        kicker="Brand Templates"
        title="Default identity for artifacts."
        description="Loading brand profile…"
      >
        <div className="mkt-page" data-page="brand">
          <div className="brand-loading">Loading brand profile...</div>
        </div>
      </AdminShell>
    );
  }

  const headerActions = (
    <label className="brand-toggle">
      <input
        type="checkbox"
        checked={Boolean(draft.active)}
        onChange={e => update('active', e.target.checked)}
      />
      <span>Use brand by default</span>
    </label>
  );

  return (
    <AdminShell
      kicker="Brand Templates"
      title="Default identity for artifacts."
      description="Upload guidelines and logos once. madarX applies the extracted system when agents create documents, presentations, and HTML artifacts."
      actions={headerActions}
    >
      <div className="mkt-page" data-page="brand">
        {notice && (
          <div className={`brand-toast ${notice.type}`} role="status" aria-live="polite">
            <span>{notice.type === 'success' ? 'Saved' : 'Needs attention'}</span>
            <p>{notice.text}</p>
            <button type="button" onClick={() => setNotice(null)} aria-label="Dismiss notification">×</button>
          </div>
        )}

        <div className="brand-grid">
          <section className="brand-panel brand-upload-panel">
            <div className="brand-panel-head">
              <span>Source Files</span>
              <small>{brand?.source_name || 'No guidelines uploaded'}</small>
            </div>
            <div className="brand-upload-row">
              <label className="brand-file-picker">
                <input type="file" accept=".html,.htm,.md,.txt,.css,.svg,.pdf" onChange={e => upload('guidelines', e.target.files?.[0])} />
                <span>
                  <b>Brand guidelines</b>
                  <small>{uploading === 'guidelines' ? 'Extracting file...' : brand?.source_name || 'HTML, Markdown, text, CSS, SVG, or PDF'}</small>
                </span>
                <em>{uploading === 'guidelines' ? 'Working' : 'Choose File'}</em>
              </label>
            </div>
            <div className="brand-upload-row">
              <label className="brand-file-picker">
                <input type="file" accept=".svg,.png,.jpg,.jpeg,.webp" onChange={e => upload('logo', e.target.files?.[0])} />
                <span>
                  <b>Primary logo</b>
                  <small>{uploading === 'logo' ? 'Saving file...' : brand?.logo_path || 'SVG, PNG, JPG, JPEG, or WebP'}</small>
                </span>
                <em>{uploading === 'logo' ? 'Working' : 'Choose File'}</em>
              </label>
            </div>
            <div className="brand-paths">
              <span>Guidelines: {brand?.guidelines_path || 'default brand-assets/brand-guidelines.html'}</span>
              <span>Logo: {brand?.logo_path || 'default brand-assets/madarx-logo-primary.svg'}</span>
            </div>
          </section>

          <section className="brand-panel brand-preview-panel" style={{ '--brand-accent': accent }}>
            <div className="brand-preview-card">
              {draft.logo_data_url && <img src={draft.logo_data_url} alt="" />}
              <span>{draft.company_name || 'Brand'}</span>
              <h2>{draft.tagline || 'Presentation-ready brand system'}</h2>
              <p>{draft.presentation_style}</p>
              <div className="brand-swatches">
                {(brand?.colors || []).slice(0, 6).map(c => (
                  <i key={`${c.name}-${c.value}`} title={`${c.name}: ${c.value}`} style={{ background: c.value }} />
                ))}
              </div>
            </div>
          </section>

          <ShareCard share={share} sharing={sharing} onShare={doShare} />

          <section className="brand-panel">
            <div className="brand-panel-head">
              <span>Identity</span>
              <small>Used in document headers and agent instructions</small>
            </div>
            <label className="brand-field">
              <span>Company name</span>
              <input value={draft.company_name || ''} onChange={e => update('company_name', e.target.value)} />
            </label>
            <label className="brand-field">
              <span>Tagline or description</span>
              <textarea rows={3} value={draft.tagline || ''} onChange={e => update('tagline', e.target.value)} />
            </label>
            <label className="brand-field">
              <span>Presentation style</span>
              <textarea rows={5} value={draft.presentation_style || ''} onChange={e => update('presentation_style', e.target.value)} />
            </label>
          </section>

          <section className="brand-panel">
            <div className="brand-panel-head">
              <span>Extracted Tokens</span>
              <small>Edit anything the extractor missed</small>
            </div>
            <label className="brand-field">
              <span>Colors, one per line</span>
              <textarea rows={7} value={draft.colors_text || ''} onChange={e => update('colors_text', e.target.value)} />
            </label>
            <label className="brand-field">
              <span>Fonts, one per line</span>
              <textarea rows={4} value={draft.fonts_text || ''} onChange={e => update('fonts_text', e.target.value)} />
            </label>
          </section>

          <section className="brand-panel">
            <div className="brand-panel-head">
              <span>Usage Defaults</span>
              <small>What agents should create with this brand</small>
            </div>
            <label className="brand-field">
              <span>Document and presentation types</span>
              <textarea rows={5} value={draft.document_types_text || ''} onChange={e => update('document_types_text', e.target.value)} />
            </label>
            <label className="brand-field">
              <span>Voice attributes</span>
              <textarea rows={5} value={draft.voice_text || ''} onChange={e => update('voice_text', e.target.value)} />
            </label>
          </section>

          <section className="brand-actions">
            <div className={`brand-save-status ${notice?.type || ''}`} aria-live="polite">
              {notice ? (
                <>
                  <b>{notice.type === 'success' ? 'Saved' : 'Error'}</b>
                  <span>{notice.text}</span>
                </>
              ) : (
                <>
                  <b>Ready</b>
                  <span>Save changes to make this the default brand system for agent artifacts.</span>
                </>
              )}
            </div>
            <button
              type="button"
              className="admin-button mars"
              onClick={save}
              disabled={saving}
            >
              {saving ? 'Saving...' : 'Save Brand Defaults'}
            </button>
          </section>
        </div>
      </div>
    </AdminShell>
  );
}
