'use client';

import { useEffect, useMemo, useState } from 'react';
import Link from 'next/link';
import {
  ArrowLeft, Save, Loader2, AlertCircle, ExternalLink, FileDown, Table2, Info,
} from 'lucide-react';
import { toast } from 'sonner';
import { useAuth } from '@client/contexts/AuthContext';
import { useLanguage } from '@client/contexts/LanguageContext';
import { usePageHeader } from '@client/contexts/PageHeaderContext';
import { getBranch, updateBranch, type Branch } from '@client/api/branches';
import QrDesigner from '@client/components/storefront/QrDesigner';
import type { QrStyle } from '@client/utils/qr';

interface BranchExtra extends Branch {
  slug?: string;
  storefront_enabled?: boolean;
  accepts_dine_in?: boolean;
  accepts_takeaway?: boolean;
  accepts_delivery?: boolean;
  min_order_value?: number;
  storefront_message?: string | null;
  qr_style_json?: Record<string, unknown>;
}

function slugifyClient(input: string): string {
  return input
    .toLowerCase()
    .normalize('NFKD')
    .replace(/[\u0300-\u036f]/g, '')
    .replace(/[^a-z0-9]+/g, '-')
    .replace(/^-+|-+$/g, '')
    .slice(0, 64);
}

// Linear slug test — avoids nested quantifiers that can cause ReDoS on crafted input.
// Equivalent semantics to /^[a-z0-9]+(?:-[a-z0-9]+)*$/:
// only lowercase alphanumeric + hyphens, no leading/trailing/consecutive hyphens.
function isValidSlug(s: string): boolean {
  if (!s || !/^[a-z0-9-]+$/.test(s)) return false;
  return !s.startsWith('-') && !s.endsWith('-') && !s.includes('--');
}

export default function EditorClient({ branchId }: { branchId: string }) {
  const { t } = useLanguage();
  const { setPageHeader } = usePageHeader();
  const { userRecord } = useAuth();
  const restaurantSlug = (userRecord?.restaurants?.slug as string | undefined) ?? '';
  const currency = (userRecord?.restaurants?.currency as string | undefined) ?? 'USD';

  const [branch, setBranch] = useState<BranchExtra | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [saving, setSaving] = useState(false);
  const [downloadingPdf, setDownloadingPdf] = useState(false);

  useEffect(() => {
    setPageHeader(
      t('storefront.editor.title', 'QR Storefront'),
      branch?.name || t('storefront.editor.subtitle', 'Design the QR and storefront for this branch'),
    );
  }, [setPageHeader, branch?.name, t]);

  useEffect(() => {
    let cancelled = false;
    (async () => {
      setLoading(true);
      setError(null);
      try {
        const r = await getBranch(branchId);
        if (cancelled) return;
        const b = r.branch as BranchExtra;
        // Pre-fill a suggested slug if missing so the preview never sits blank.
        if (!b.slug || b.slug.trim() === '') {
          b.slug = slugifyClient(b.name) || 'branch';
        }
        setBranch(b);
      } catch (e) {
        if (!cancelled) setError((e as Error).message ?? t('common.loadFailed', 'Failed to load'));
      } finally {
        if (!cancelled) setLoading(false);
      }
    })();
    return () => { cancelled = true; };
  }, [branchId, t]);

  const branchSlug = branch?.slug?.trim() ?? '';
  const slugValid = isValidSlug(branchSlug);

  const baseStorefrontUrl = useMemo(() => {
    if (typeof window === 'undefined' || !restaurantSlug || !branchSlug) return '';
    return `${window.location.origin}/r/${restaurantSlug}/${branchSlug}`;
  }, [restaurantSlug, branchSlug]);

  const qrStyle: QrStyle = useMemo(() => ({
    fg: (branch?.qr_style_json?.fg as string) ?? '#111827',
    bg: (branch?.qr_style_json?.bg as string) ?? '#ffffff',
    margin: (branch?.qr_style_json?.margin as number) ?? 2,
    ecc: ((branch?.qr_style_json?.ecc as 'L' | 'M' | 'Q' | 'H') ?? 'M'),
    logo_data_url: (branch?.qr_style_json?.logo_data_url as string | null) ?? null,
    frame: (branch?.qr_style_json?.frame as 'none' | 'scan-me' | null) ?? 'none',
  }), [branch?.qr_style_json]);

  const onSave = async () => {
    if (!branch) return;
    if (!slugValid) {
      toast.error(t('storefront.editor.slugInvalid', 'Slug must be lowercase letters, digits and hyphens (e.g. downtown).'));
      return;
    }
    setSaving(true);
    try {
      await updateBranch(branchId, {
        slug: branch.slug,
        storefront_enabled: branch.storefront_enabled,
        accepts_dine_in: branch.accepts_dine_in,
        accepts_takeaway: branch.accepts_takeaway,
        accepts_delivery: branch.accepts_delivery,
        min_order_value: Number(branch.min_order_value) || 0,
        storefront_message: branch.storefront_message ?? null,
        qr_style_json: branch.qr_style_json ?? {},
      });
      toast.success(t('storefront.editor.saved', 'Storefront saved'));
      // Re-fetch to reflect server-normalized slug etc.
      const r = await getBranch(branchId);
      setBranch(r.branch as BranchExtra);
    } catch (e) {
      toast.error((e as Error).message ?? t('common.saveFailed', 'Save failed'));
    } finally {
      setSaving(false);
    }
  };

  const downloadPdf = async () => {
    if (!slugValid) {
      toast.error(t('storefront.editor.savePublishFirst', 'Save the storefront with a valid slug first.'));
      return;
    }
    setDownloadingPdf(true);
    try {
      const res = await fetch(`/api/branches/${branchId}/qr-pdf`, { credentials: 'include' });
      if (!res.ok) {
        const j = (await res.json().catch(() => ({}))) as { error?: string };
        throw new Error(j.error || t('storefront.editor.pdfFailed', 'Failed to generate PDF'));
      }
      const blob = await res.blob();
      const url = URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = `qr-${branch?.slug || 'branch'}.pdf`;
      document.body.appendChild(a);
      a.click();
      setTimeout(() => { URL.revokeObjectURL(url); a.remove(); }, 0);
    } catch (e) {
      toast.error((e as Error).message ?? t('storefront.editor.pdfFailed', 'Failed to generate PDF'));
    } finally {
      setDownloadingPdf(false);
    }
  };

  if (loading) {
    return (
      <div className="p-8 flex items-center justify-center text-slate-500">
        <Loader2 className="animate-spin mr-2" /> {t('common.loading', 'Loading…')}
      </div>
    );
  }
  if (error || !branch) {
    return (
      <div className="p-8 text-red-600 flex items-center gap-2">
        <AlertCircle size={18} /> {error ?? t('storefront.editor.notFound', 'Branch not found')}
      </div>
    );
  }

  return (
    <div className="p-6 max-w-5xl mx-auto">
      <Link href="/storefront?all=1" className="inline-flex items-center gap-1 text-sm text-slate-500 hover:text-slate-700 mb-4">
        <ArrowLeft size={14} /> {t('storefront.editor.backToList', 'Back to QR Storefront')}
      </Link>

      <div className="flex items-center justify-between mb-6 flex-wrap gap-3">
        <div>
          <h1 className="text-2xl font-bold text-slate-900">{branch.name}</h1>
          <p className="text-sm text-slate-500">{branch.address || '—'}</p>
        </div>
        <div className="flex items-center gap-2 flex-wrap">
          {baseStorefrontUrl && slugValid && (
            <a
              href={baseStorefrontUrl}
              target="_blank"
              rel="noopener noreferrer"
              className="inline-flex items-center gap-1.5 text-sm font-semibold text-slate-700 bg-white border border-slate-200 hover:bg-slate-50 px-3 py-2 rounded-lg"
            >
              <ExternalLink size={14} /> {t('storefront.editor.openPublic', 'Open public storefront')}
            </a>
          )}
          <Link
            href={`/branch-management/${branchId}/tables`}
            className="inline-flex items-center gap-1.5 text-sm font-semibold text-slate-700 bg-white border border-slate-200 hover:bg-slate-50 px-3 py-2 rounded-lg"
          >
            <Table2 size={14} /> {t('storefront.editor.manageTables', 'Manage tables')}
          </Link>
          <button
            onClick={downloadPdf}
            disabled={downloadingPdf || !slugValid}
            className="inline-flex items-center gap-1.5 text-sm font-semibold bg-slate-900 hover:bg-slate-800 disabled:bg-slate-300 text-white px-3 py-2 rounded-lg"
          >
            {downloadingPdf ? <Loader2 size={14} className="animate-spin" /> : <FileDown size={14} />}
            {t('storefront.editor.downloadPdf', 'Print-ready PDF')}
          </button>
        </div>
      </div>

      <div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
        {/* QR designer (spans 2 cols on desktop) */}
        <section className="lg:col-span-2 bg-white border border-slate-200 rounded-xl p-5">
          <h2 className="font-semibold text-slate-900 mb-1">{t('storefront.editor.qrDesignTitle', 'QR design')}</h2>
          <p className="text-xs text-slate-500 mb-4">
            {t('storefront.editor.qrDesignHelp', 'This style is used for every table QR card and the printed PDF. Changes preview live.')}
          </p>
          {baseStorefrontUrl ? (
            <QrDesigner
              url={baseStorefrontUrl}
              style={qrStyle}
              onChange={(s) => setBranch({ ...branch, qr_style_json: { ...(branch.qr_style_json ?? {}), ...s } })}
              filename={`qr-${branchSlug || 'branch'}`}
              caption={t('storefront.editor.qrCaption', 'Branch storefront')}
            />
          ) : (
            <div className="text-sm text-slate-500">
              {t('storefront.editor.restaurantSlugMissing', 'Set a restaurant slug in Settings before designing the QR.')}
            </div>
          )}
        </section>

        {/* Storefront settings */}
        <section className="bg-white border border-slate-200 rounded-xl p-5 space-y-4">
          <h2 className="font-semibold text-slate-900">{t('storefront.editor.settingsTitle', 'Storefront settings')}</h2>

          <div>
            <label className="text-xs font-semibold text-slate-700">{t('storefront.editor.slug', 'Branch slug')}</label>
            <input
              value={branch.slug ?? ''}
              onChange={(e) => setBranch({ ...branch, slug: e.target.value })}
              onBlur={(e) => {
                const v = e.target.value.trim();
                if (v && !isValidSlug(v)) {
                  setBranch({ ...branch, slug: slugifyClient(v) });
                }
              }}
              className={`mt-1 w-full rounded-lg border px-3 py-2 text-sm ${slugValid ? 'border-slate-200' : 'border-rose-300 bg-rose-50'}`}
              placeholder={t('storefront.editor.slugPlaceholder', 'downtown')}
            />
            <p className="text-[11px] text-slate-400 mt-1">
              {t('storefront.editor.slugHelp', 'Used in the public URL — lowercase letters, digits, hyphens.')}
            </p>
            {restaurantSlug && branchSlug && (
              <p className="text-[11px] text-slate-500 mt-1 break-all">
                /r/{restaurantSlug}/<span className="font-mono">{branchSlug}</span>
              </p>
            )}
          </div>

          <Toggle
            label={t('storefront.editor.enabled', 'Storefront enabled')}
            checked={!!branch.storefront_enabled}
            onChange={(v) => setBranch({ ...branch, storefront_enabled: v })}
          />
          <Toggle
            label={t('storefront.editor.dineIn', 'Accept dine-in (QR table)')}
            checked={!!branch.accepts_dine_in}
            onChange={(v) => setBranch({ ...branch, accepts_dine_in: v })}
          />
          <Toggle
            label={t('storefront.editor.takeaway', 'Accept takeaway / pickup')}
            checked={!!branch.accepts_takeaway}
            onChange={(v) => setBranch({ ...branch, accepts_takeaway: v })}
          />
          <Toggle
            label={t('storefront.editor.delivery', 'Accept delivery')}
            checked={!!branch.accepts_delivery}
            onChange={(v) => setBranch({ ...branch, accepts_delivery: v })}
          />

          <div>
            <label className="text-xs font-semibold text-slate-700">
              {t('storefront.editor.minOrder', 'Minimum order')} ({currency})
            </label>
            <input
              type="number" step="0.01" min={0}
              value={branch.min_order_value ?? 0}
              onChange={(e) => setBranch({ ...branch, min_order_value: Number(e.target.value) })}
              className="mt-1 w-full rounded-lg border border-slate-200 px-3 py-2 text-sm"
            />
          </div>

          <div>
            <label className="text-xs font-semibold text-slate-700">{t('storefront.editor.banner', 'Storefront banner message')}</label>
            <textarea
              value={branch.storefront_message ?? ''}
              onChange={(e) => setBranch({ ...branch, storefront_message: e.target.value })}
              rows={2}
              maxLength={200}
              className="mt-1 w-full rounded-lg border border-slate-200 px-3 py-2 text-sm"
              placeholder={t('storefront.editor.bannerPlaceholder', 'Holiday hours, special promo, etc.')}
            />
          </div>

          <div className="rounded-lg bg-amber-50 border border-amber-200 px-3 py-2 text-xs text-amber-800 flex gap-2">
            <Info size={14} className="shrink-0 mt-0.5" />
            <span>{t('storefront.editor.payInPersonNote', 'Storefront orders are pay-in-person (cash on delivery / pay at counter).')}</span>
          </div>

          <button
            onClick={onSave}
            disabled={saving}
            className="w-full inline-flex items-center justify-center gap-1.5 bg-orange-500 hover:bg-orange-600 text-white rounded-lg px-4 py-2 text-sm font-semibold disabled:opacity-50"
          >
            {saving ? <Loader2 size={14} className="animate-spin" /> : <Save size={14} />}
            {t('storefront.editor.save', 'Save storefront & QR')}
          </button>
        </section>
      </div>
    </div>
  );
}

function Toggle({ label, checked, onChange }: { label: string; checked: boolean; onChange: (v: boolean) => void }) {
  return (
    <label className="flex items-center justify-between gap-4 py-1 cursor-pointer">
      <span className="text-sm text-slate-700">{label}</span>
      <button
        type="button"
        role="switch"
        aria-checked={checked}
        aria-label={label}
        onClick={() => onChange(!checked)}
        className={`relative w-11 h-6 rounded-full transition-colors focus:outline-none focus:ring-2 focus:ring-orange-400 focus:ring-offset-1 ${checked ? 'bg-orange-500' : 'bg-slate-300'}`}
      >
        <span className={`absolute top-0.5 left-0.5 w-5 h-5 rounded-full bg-white shadow transition-transform ${checked ? 'translate-x-5' : ''}`} />
      </button>
    </label>
  );
}
