'use client';

import Link from 'next/link';
import { useRouter } from 'next/navigation';
import { useEffect, useMemo, useState } from 'react';

type ClubMode = 'landing' | 'join' | 'card';

type ClubConfig = {
  clubEnabled: boolean;
  cashbackBps: number;
  cashbackPercentage: number;
  allowAnonymousMembers: boolean;
  allowRecoveryCodes: boolean;
  minimumRedeemAmountCents: number;
};

type ClubMember = {
  id: string;
  userId: string | null;
  memberCode: string;
  status: 'active' | 'blocked' | 'merged';
  tierCode: string;
  currentBalanceCents: number;
  isAnonymous: boolean;
  createdAt: string;
  updatedAt: string;
};

type ClubMovement = {
  id: string;
  type: 'earn' | 'redeem' | 'refund' | 'bonus' | 'adjustment';
  amountCents: number;
  balanceDeltaCents: number;
  createdAt: string;
};

type ClubMeResponse = {
  member: ClubMember;
  config: ClubConfig;
};

type ClubMovementsResponse = {
  member: ClubMember;
  items: ClubMovement[];
};

type ClubJoinResponse = {
  created: boolean;
  deviceToken: string;
  member: ClubMember;
  config: ClubConfig;
};

type BeforeInstallPromptEvent = Event & {
  prompt: () => Promise<void>;
  userChoice: Promise<{ outcome: 'accepted' | 'dismissed'; platform: string }>;
};

function formatMoney(cents: number): string {
  return new Intl.NumberFormat('es-ES', {
    style: 'currency',
    currency: 'EUR',
  }).format(cents / 100);
}

function movementLabel(type: ClubMovement['type']): string {
  switch (type) {
    case 'earn':
      return 'Acumulación';
    case 'redeem':
      return 'Canje';
    case 'refund':
      return 'Reembolso';
    case 'bonus':
      return 'Bono';
    case 'adjustment':
      return 'Ajuste';
    default:
      return type;
  }
}

async function readJson<T>(input: RequestInfo, init?: RequestInit): Promise<T> {
  const response = await fetch(input, { ...init, credentials: 'include', cache: 'no-store' });
  const data = (await response.json().catch(() => ({}))) as { error?: { message?: string } } & T;
  if (!response.ok) {
    throw new Error(data.error?.message || 'No se pudo completar la operación del Club');
  }
  return data;
}

function isDisplayStandalone(): boolean {
  if (typeof window === 'undefined') return false;
  const navigatorWithStandalone = window.navigator as Navigator & { standalone?: boolean };
  return window.matchMedia('(display-mode: standalone)').matches || navigatorWithStandalone.standalone === true;
}

function isIosDevice(): boolean {
  if (typeof window === 'undefined') return false;
  return /iphone|ipad|ipod/i.test(window.navigator.userAgent);
}

function buildVisualCode(seed: string): boolean[][] {
  const size = 21;
  const grid = Array.from({ length: size }, () => Array.from({ length: size }, () => false));

  const drawFinder = (startRow: number, startCol: number) => {
    for (let row = 0; row < 7; row += 1) {
      for (let col = 0; col < 7; col += 1) {
        const edge = row === 0 || row === 6 || col === 0 || col === 6;
        const center = row >= 2 && row <= 4 && col >= 2 && col <= 4;
        grid[startRow + row]![startCol + col] = edge || center;
      }
    }
  };

  drawFinder(0, 0);
  drawFinder(0, size - 7);
  drawFinder(size - 7, 0);

  let hash = 0;
  for (let index = 0; index < seed.length; index += 1) {
    hash = (hash * 33 + seed.charCodeAt(index)) >>> 0;
  }

  for (let row = 0; row < size; row += 1) {
    for (let col = 0; col < size; col += 1) {
      const inFinder =
        (row < 7 && col < 7) ||
        (row < 7 && col >= size - 7) ||
        (row >= size - 7 && col < 7);
      if (inFinder) continue;
      const bit = ((hash >> ((row + col) % 24)) ^ ((row + 1) * 17) ^ ((col + 1) * 31)) & 1;
      grid[row]![col] = bit === 1;
      hash = ((hash * 1664525 + 1013904223) >>> 0) ^ (row * 97 + col * 53);
    }
  }

  return grid;
}

function InstallButton() {
  const [installEvent, setInstallEvent] = useState<BeforeInstallPromptEvent | null>(null);
  const [installed, setInstalled] = useState(false);

  useEffect(() => {
    setInstalled(isDisplayStandalone());
    const handlePrompt = (event: Event) => {
      event.preventDefault();
      setInstallEvent(event as BeforeInstallPromptEvent);
    };
    const handleInstalled = () => {
      setInstalled(true);
      setInstallEvent(null);
    };
    window.addEventListener('beforeinstallprompt', handlePrompt);
    window.addEventListener('appinstalled', handleInstalled);
    return () => {
      window.removeEventListener('beforeinstallprompt', handlePrompt);
      window.removeEventListener('appinstalled', handleInstalled);
    };
  }, []);

  if (installed) {
    return (
      <div className="rounded-2xl border border-emerald-200 bg-emerald-50 px-4 py-3 text-sm text-emerald-800">
        La app del Club ya está instalada en este dispositivo.
      </div>
    );
  }

  if (installEvent) {
    return (
      <button
        type="button"
        onClick={async () => {
          await installEvent.prompt();
          await installEvent.userChoice.catch(() => undefined);
          setInstallEvent(null);
        }}
        className="inline-flex items-center justify-center rounded-full bg-[#1B4332] px-5 py-3 text-sm font-semibold text-white transition-colors hover:bg-[#163826]"
      >
        Instalar app del Club
      </button>
    );
  }

  if (isIosDevice()) {
    return (
      <div className="rounded-2xl border border-stone-200 bg-white px-4 py-3 text-sm text-stone-600">
        En iPhone o iPad puedes instalarla desde Compartir → <strong>Añadir a pantalla de inicio</strong>.
      </div>
    );
  }

  return null;
}

function MemberVisualCode({ memberCode }: { memberCode: string }) {
  const cells = useMemo(() => buildVisualCode(memberCode), [memberCode]);
  return (
    <svg viewBox="0 0 210 210" className="h-44 w-44 rounded-3xl bg-white p-4 shadow-inner">
      <rect width="210" height="210" rx="24" fill="white" />
      {cells.flatMap((row, rowIndex) =>
        row.map((value, colIndex) =>
          value ? (
            <rect
              key={`${rowIndex}-${colIndex}`}
              x={colIndex * 10}
              y={rowIndex * 10}
              width="10"
              height="10"
              rx="2"
              fill="#1B4332"
            />
          ) : null,
        ),
      )}
    </svg>
  );
}

function MovementList({ items }: { items: ClubMovement[] }) {
  if (items.length === 0) {
    return (
      <div className="rounded-2xl border border-dashed border-stone-300 bg-white px-4 py-8 text-center text-sm text-stone-500">
        Aún no hay movimientos. Cuando empieces a usar el Club aparecerán aquí.
      </div>
    );
  }

  return (
    <div className="space-y-3">
      {items.map((item) => {
        const positive = item.balanceDeltaCents > 0;
        return (
          <div
            key={item.id}
            className="flex items-center justify-between rounded-2xl border border-stone-200 bg-white px-4 py-3"
          >
            <div>
              <p className="text-sm font-semibold text-stone-900">{movementLabel(item.type)}</p>
              <p className="text-xs text-stone-500">
                {new Date(item.createdAt).toLocaleString('es-ES', {
                  day: '2-digit',
                  month: '2-digit',
                  year: 'numeric',
                  hour: '2-digit',
                  minute: '2-digit',
                })}
              </p>
            </div>
            <div className="text-right">
              <p className={`text-sm font-semibold ${positive ? 'text-emerald-700' : 'text-stone-700'}`}>
                {positive ? '+' : ''}{formatMoney(item.balanceDeltaCents)}
              </p>
              <p className="text-xs text-stone-500">Base {formatMoney(item.amountCents)}</p>
            </div>
          </div>
        );
      })}
    </div>
  );
}

export function ClubExperience({ mode }: { mode: ClubMode }) {
  const router = useRouter();
  const [config, setConfig] = useState<ClubConfig | null>(null);
  const [member, setMember] = useState<ClubMember | null>(null);
  const [movements, setMovements] = useState<ClubMovement[]>([]);
  const [loading, setLoading] = useState(true);
  const [joining, setJoining] = useState(false);
  const [error, setError] = useState('');

  useEffect(() => {
    let cancelled = false;
    (async () => {
      setLoading(true);
      setError('');
      try {
        const publicConfig = await readJson<ClubConfig>('/api/club/config');
        if (cancelled) return;
        setConfig(publicConfig);
        try {
          const me = await readJson<ClubMeResponse>('/api/club/me');
          if (cancelled) return;
          setMember(me.member);
          setConfig(me.config);
          const latest = await readJson<ClubMovementsResponse>('/api/club/movements?limit=5');
          if (cancelled) return;
          setMovements(latest.items ?? []);
        } catch {
          if (cancelled) return;
          setMember(null);
          setMovements([]);
        }
      } catch (err) {
        if (cancelled) return;
        setError(err instanceof Error ? err.message : 'No se pudo cargar el Club');
      } finally {
        if (!cancelled) setLoading(false);
      }
    })();
    return () => {
      cancelled = true;
    };
  }, []);

  const handleJoin = async () => {
    setJoining(true);
    setError('');
    try {
      const response = await readJson<ClubJoinResponse>('/api/club/join', { method: 'POST' });
      setMember(response.member);
      setConfig(response.config);
      setMovements([]);
      router.push('/club/card');
    } catch (err) {
      setError(err instanceof Error ? err.message : 'No se pudo darte de alta en el Club');
    } finally {
      setJoining(false);
    }
  };

  const benefits = [
    `Cashback configurable actualmente al ${config?.cashbackPercentage ?? 2}%`,
    'Tarjeta digital siempre disponible en tu móvil',
    'Historial de movimientos y saldo desde la misma app',
  ];

  if (loading) {
    return (
      <section className="mx-auto max-w-4xl px-4 py-16 sm:px-6 lg:px-8">
        <div className="rounded-[2rem] border border-stone-200 bg-white px-6 py-16 text-center text-stone-500 shadow-sm">
          Cargando Club…
        </div>
      </section>
    );
  }

  if (error && !config) {
    return (
      <section className="mx-auto max-w-4xl px-4 py-16 sm:px-6 lg:px-8">
        <div className="rounded-[2rem] border border-red-200 bg-red-50 px-6 py-16 text-center text-red-700 shadow-sm">
          {error}
        </div>
      </section>
    );
  }

  const disabled = config && (!config.clubEnabled || !config.allowAnonymousMembers);

  return (
    <section className="bg-[radial-gradient(circle_at_top,_rgba(112,173,71,0.18),_transparent_45%)]">
      <div className="mx-auto max-w-5xl px-4 py-10 sm:px-6 lg:px-8">
        <div className="grid gap-6 lg:grid-cols-[1.1fr_0.9fr]">
          <div className="rounded-[2rem] bg-[#163826] p-8 text-white shadow-xl">
            <p className="text-sm font-semibold uppercase tracking-[0.25em] text-[#CFE7B8]">Club Mercado de Vida</p>
            <h1 className="mt-3 text-3xl font-bold sm:text-4xl">
              {mode === 'card' ? 'Tu tarjeta digital del Club' : 'Lleva tu Club siempre contigo'}
            </h1>
            <p className="mt-4 max-w-xl text-sm leading-7 text-[#E8F5E0] sm:text-base">
              Únete en segundos, consulta tu saldo y abre tu tarjeta del Club desde el móvil como una app instalada.
            </p>

            <div className="mt-8 flex flex-wrap gap-3">
              {member ? (
                <Link
                  href="/club/card"
                  className="inline-flex items-center justify-center rounded-full bg-white px-5 py-3 text-sm font-semibold text-[#163826] transition-colors hover:bg-[#F5F9EF]"
                >
                  Abrir mi tarjeta
                </Link>
              ) : (
                <button
                  type="button"
                  onClick={handleJoin}
                  disabled={joining || Boolean(disabled)}
                  className="inline-flex items-center justify-center rounded-full bg-white px-5 py-3 text-sm font-semibold text-[#163826] transition-colors hover:bg-[#F5F9EF] disabled:cursor-not-allowed disabled:opacity-60"
                >
                  {joining ? 'Activando…' : 'Unirme al Club'}
                </button>
              )}
              <Link
                href="/club/join"
                className="inline-flex items-center justify-center rounded-full border border-white/30 px-5 py-3 text-sm font-semibold text-white transition-colors hover:bg-white/10"
              >
                Ver acceso rápido
              </Link>
            </div>

            {error && (
              <div className="mt-4 rounded-2xl border border-red-300/30 bg-red-500/10 px-4 py-3 text-sm text-red-100">
                {error}
              </div>
            )}

            <div className="mt-8 grid gap-3 sm:grid-cols-3">
              {benefits.map((benefit) => (
                <div key={benefit} className="rounded-2xl border border-white/10 bg-white/5 px-4 py-4 text-sm text-[#E8F5E0]">
                  {benefit}
                </div>
              ))}
            </div>
          </div>

          <div className="space-y-6">
            <div className="rounded-[2rem] border border-stone-200 bg-[#F5F9EF] p-6 shadow-sm">
              <div className="flex items-start justify-between gap-4">
                <div>
                  <p className="text-xs font-semibold uppercase tracking-[0.25em] text-[#70AD47]">Club card</p>
                  <h2 className="mt-2 text-2xl font-bold text-stone-900">
                    {member ? member.memberCode : 'Activa tu tarjeta'}
                  </h2>
                  <p className="mt-2 text-sm text-stone-600">
                    {member
                      ? 'Tu tarjeta digital queda guardada en este dispositivo para abrirla al instante.'
                      : 'Date de alta una vez y tendrás tu credencial digital siempre a mano.'}
                  </p>
                </div>
                <span className="rounded-full bg-white px-3 py-1 text-xs font-semibold text-stone-600 shadow-sm">
                  {member ? 'Activa' : 'Lista para activar'}
                </span>
              </div>

              <div className="mt-6 rounded-[2rem] bg-gradient-to-br from-[#70AD47] via-[#5A9040] to-[#2D6A4F] p-5 text-white shadow-lg">
                <div className="flex items-start justify-between gap-4">
                  <div>
                    <p className="text-xs uppercase tracking-[0.25em] text-white/80">Saldo Club</p>
                    <p className="mt-2 text-3xl font-bold">{formatMoney(member?.currentBalanceCents ?? 0)}</p>
                    <p className="mt-2 text-sm text-white/80">Canje mínimo: {formatMoney(config?.minimumRedeemAmountCents ?? 500)}</p>
                  </div>
                  <MemberVisualCode memberCode={member?.memberCode ?? 'MDV-CLUB-DEMO'} />
                </div>
                <div className="mt-4 flex items-center justify-between rounded-2xl bg-black/10 px-4 py-3 text-sm text-white/90">
                  <span>{member?.memberCode ?? 'Activa tu member code'}</span>
                  <span>{member?.isAnonymous ? 'Modo anónimo' : 'Cuenta vinculada'}</span>
                </div>
              </div>
            </div>

            <div className="rounded-[2rem] border border-stone-200 bg-white p-6 shadow-sm">
              <div className="flex items-center justify-between gap-4">
                <div>
                  <h3 className="text-lg font-bold text-stone-900">Instalación rápida</h3>
                  <p className="mt-1 text-sm text-stone-600">Añade el Club a tu pantalla de inicio para abrir la tarjeta como una app.</p>
                </div>
              </div>
              <div className="mt-4">
                <InstallButton />
              </div>
            </div>
          </div>
        </div>

        <div className="mt-6 grid gap-6 lg:grid-cols-[0.95fr_1.05fr]">
          <div className="rounded-[2rem] border border-stone-200 bg-white p-6 shadow-sm">
            <div className="flex items-center justify-between gap-4">
              <div>
                <h2 className="text-lg font-bold text-stone-900">
                  {mode === 'join' ? 'Alta rápida' : 'Estado del Club'}
                </h2>
                <p className="mt-1 text-sm text-stone-600">
                  {disabled
                    ? 'El Club está temporalmente desactivado desde configuración.'
                    : member
                      ? 'Tu dispositivo ya tiene una identidad Club activa.'
                      : 'Puedes darte de alta en segundos desde este dispositivo.'}
                </p>
              </div>
              {member && (
                <Link href="/club/card" className="text-sm font-semibold text-[#2D6A4F] hover:text-[#1B4332]">
                  Abrir tarjeta →
                </Link>
              )}
            </div>

            <div className="mt-5 space-y-3 text-sm text-stone-700">
              <div className="rounded-2xl bg-stone-50 px-4 py-3">
                <span className="font-semibold text-stone-900">Cashback configurado:</span>{' '}
                {config?.cashbackPercentage ?? 2}%
              </div>
              <div className="rounded-2xl bg-stone-50 px-4 py-3">
                <span className="font-semibold text-stone-900">Recovery codes:</span>{' '}
                {config?.allowRecoveryCodes ? 'preparados para fases futuras' : 'desactivados'}
              </div>
              <div className="rounded-2xl bg-stone-50 px-4 py-3">
                <span className="font-semibold text-stone-900">Identidad actual:</span>{' '}
                {member ? member.memberCode : 'sin activar todavía'}
              </div>
            </div>

            {!member && (
              <div className="mt-6 space-y-3">
                <button
                  type="button"
                  onClick={handleJoin}
                  disabled={joining || Boolean(disabled)}
                  className="inline-flex w-full items-center justify-center rounded-2xl bg-[#70AD47] px-5 py-3 text-sm font-semibold text-white transition-colors hover:bg-[#5A9040] disabled:cursor-not-allowed disabled:opacity-60"
                >
                  {joining ? 'Creando tarjeta…' : 'Crear mi tarjeta del Club'}
                </button>
                {disabled && (
                  <p className="text-sm text-stone-500">
                    Ahora mismo no se permiten nuevas altas anónimas desde la configuración del Club.
                  </p>
                )}
              </div>
            )}
          </div>

          <div className="rounded-[2rem] border border-stone-200 bg-white p-6 shadow-sm">
            <div className="flex items-center justify-between gap-4">
              <div>
                <h2 className="text-lg font-bold text-stone-900">Últimos movimientos</h2>
                <p className="mt-1 text-sm text-stone-600">Los eventos del ledger del Club aparecerán aquí.</p>
              </div>
              {member && (
                <span className="rounded-full bg-stone-100 px-3 py-1 text-xs font-semibold text-stone-600">
                  {movements.length} visibles
                </span>
              )}
            </div>
            <div className="mt-5">
              <MovementList items={member ? movements : []} />
            </div>
          </div>
        </div>
      </div>
    </section>
  );
}
