'use client';

import Link from 'next/link';
import Image from 'next/image';
import { useRouter } from 'next/navigation';
import { ChangeEvent, useEffect, useMemo, useState } from 'react';
import { formatCep, lookupCep } from '../../lib/cep';
import { PublicFlowNav } from '../public-flow-nav';
import {
  calculateCartPricing,
  createPublicOrder,
  createPublicPaymentIntent,
  defaultOrderState,
  fetchStorefront,
  formatCurrency,
  readOrderState,
  type CartItem,
  type CheckoutProfile,
  type Storefront,
  writeOrderState,
} from '../lib/public-order-store';

export default function PublicOrderCartPage() {
  const router = useRouter();
  const [items, setItems] = useState<CartItem[]>([]);
  const [storefront, setStorefront] = useState<Storefront | null>(null);
  const [couponCode, setCouponCode] = useState('');
  const [values, setValues] = useState<CheckoutProfile>(defaultOrderState.checkout);
  const [acceptsCashOnDelivery, setAcceptsCashOnDelivery] = useState(false);
  const [cepError, setCepError] = useState('');
  const [lookingUpCep, setLookingUpCep] = useState(false);
  const [intentLoading, setIntentLoading] = useState(false);
  const [submitting, setSubmitting] = useState(false);
  const [error, setError] = useState('');
  const [copied, setCopied] = useState(false);

  useEffect(() => {
    const state = readOrderState();
    setItems(state.cart);
    setCouponCode(state.checkout.couponCode ?? '');
    setValues({ ...defaultOrderState.checkout, ...state.checkout });
    void fetchStorefront(state.restaurantSlug)
      .then((payload) => {
        setStorefront(payload);
        setAcceptsCashOnDelivery(Boolean(payload.acceptsCashOnDelivery));
      })
      .catch(() => setStorefront(null));
  }, []);

  const pricing = useMemo(
    () =>
      calculateCartPricing(
        {
          ...defaultOrderState,
          ...readOrderState(),
          cart: items,
          checkout: { ...defaultOrderState.checkout, ...values, couponCode },
        },
        storefront,
      ),
    [items, couponCode, storefront, values],
  );

  const updateState = (
    nextItems: CartItem[],
    nextCouponCode = couponCode,
    nextCheckout: CheckoutProfile = { ...values, couponCode: nextCouponCode },
  ) => {
    const state = readOrderState();
    writeOrderState({
      ...defaultOrderState,
      ...state,
      cart: nextItems,
      checkout: { ...defaultOrderState.checkout, ...state.checkout, ...nextCheckout, couponCode: nextCouponCode },
    });
    setItems(nextItems);
    setCouponCode(nextCouponCode);
    setValues({ ...nextCheckout, couponCode: nextCouponCode });
  };

  const updateQuantity = (itemId: string, quantity: number) => {
    const nextItems = items
      .map((item) => (item.id === itemId ? { ...item, quantity: Math.max(0, quantity) } : item))
      .filter((item) => item.quantity > 0);
    updateState(nextItems);
  };

  const handleChange = (key: keyof CheckoutProfile) => (event: ChangeEvent<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>) => {
    const next = {
      ...values,
      [key]: key === 'zipCode' ? formatCep(event.target.value) : event.target.value,
    };
    updateState(items, couponCode, next);
  };

  const handleLookupCep = async () => {
    setCepError('');
    setLookingUpCep(true);
    try {
      const payload = await lookupCep(values.zipCode);
      const next = {
        ...values,
        zipCode: payload.zipCode,
        street: payload.street || values.street,
        neighborhood: payload.neighborhood || values.neighborhood,
        city: payload.city || values.city,
        state: payload.state || values.state,
        complement: values.complement || payload.complement,
      };
      updateState(items, couponCode, next);
    } catch (lookupError) {
      setCepError(lookupError instanceof Error ? lookupError.message : 'Falha ao consultar o CEP.');
    } finally {
      setLookingUpCep(false);
    }
  };

  const paymentMethods = [
    ['PIX', 'PIX imediato'],
    ['CREDIT_CARD', 'Cartao salvo'],
    ...(acceptsCashOnDelivery ? [['CASH', 'Pagamento na entrega']] : []),
  ] as Array<[CheckoutProfile['paymentMethod'], string]>;

  const completion = useMemo(() => {
    const required = [values.fullName, values.phone, values.street, values.number, values.neighborhood, values.city, values.state, values.zipCode];
    return Math.round((required.filter(Boolean).length / required.length) * 100);
  }, [values]);

  const prepareIntent = async () => {
    const state = readOrderState();
    setIntentLoading(true);
    setError('');
    try {
      const payload = await createPublicPaymentIntent(state, pricing.total);
      writeOrderState({ ...state, paymentIntent: payload });
      return payload;
    } catch (intentError) {
      setError(intentError instanceof Error ? intentError.message : 'Falha ao preparar pagamento.');
      return null;
    } finally {
      setIntentLoading(false);
    }
  };

  const submit = async () => {
    setSubmitting(true);
    setError('');
    try {
      if (items.length === 0) {
        throw new Error('Adicione pelo menos um item antes de finalizar.');
      }
      const intent = await prepareIntent();
      if (!intent) {
        setSubmitting(false);
        return;
      }
      const state = readOrderState();
      const order = await createPublicOrder(state);
      writeOrderState({
        ...defaultOrderState,
        restaurantSlug: state.restaurantSlug,
        checkout: state.checkout,
        cart: [],
        paymentIntent: intent,
        lastOrder: { id: order.id, total: order.summary.total, etaMinutes: order.etaMinutes },
      });
      router.push(`/public-order/order-confirmed?orderId=${order.id}&eta=${order.etaMinutes}&total=${order.summary.total}`);
    } catch (submitError) {
      setError(submitError instanceof Error ? submitError.message : 'Falha ao criar pedido.');
      setSubmitting(false);
    }
  };

  const currentIntent = readOrderState().paymentIntent ?? null;

  const copyPixCode = async () => {
    if (!currentIntent?.pix?.qrCodeText) return;
    await navigator.clipboard.writeText(currentIntent.pix.qrCodeText);
    setCopied(true);
    window.setTimeout(() => setCopied(false), 2500);
  };

  return (
    <main className="min-h-screen bg-[#f7f7f8] px-4 py-4 text-slate-950 lg:px-8 lg:py-6">
      <div className="mx-auto grid max-w-6xl gap-5 xl:grid-cols-[1.1fr_0.9fr]">
        <div className="xl:col-span-2">
          <PublicFlowNav />
        </div>

        <section className="rounded-[2rem] bg-white p-5 shadow-[0_14px_40px_rgba(15,23,42,0.06)]">
          <div className="flex items-center justify-between gap-4">
            <div>
              <p className="text-xs font-black uppercase tracking-[0.2em] text-slate-400">Carrinho</p>
              <h1 className="mt-2 text-3xl font-black tracking-tight text-slate-950">Revise seu pedido</h1>
            </div>
            <span className="rounded-full bg-slate-100 px-4 py-2 text-sm font-black text-slate-700">
              {items.length} itens
            </span>
          </div>

          <div className="mt-6 space-y-4">
            {items.length === 0 ? (
              <p className="rounded-[1.4rem] border border-slate-200 bg-slate-50 px-4 py-4 text-sm text-slate-600">
                Seu carrinho ainda esta vazio.
              </p>
            ) : null}

            {items.map((item) => (
              <article
                key={item.id}
                className="rounded-[1.5rem] border border-slate-200 bg-slate-50 px-4 py-4"
              >
                <div className="flex items-start justify-between gap-4">
                  <div>
                    <p className="text-lg font-black text-slate-900">{item.name}</p>
                    {item.selectedVariation ? (
                      <p className="mt-2 text-sm text-slate-600">
                        Variacao: {item.selectedVariation.name}
                      </p>
                    ) : null}
                    {item.selectedAdditionals.length ? (
                      <p className="mt-1 text-sm text-slate-600">
                        Adicionais: {item.selectedAdditionals.map((additional) => additional.name).join(', ')}
                      </p>
                    ) : null}
                    {item.notes ? <p className="mt-1 text-sm text-slate-500">{item.notes}</p> : null}
                    <div className="mt-3 flex items-center gap-3">
                      <button
                        type="button"
                        onClick={() => updateQuantity(item.id, item.quantity - 1)}
                        className="inline-flex h-8 w-8 items-center justify-center rounded-full border border-slate-200 bg-white text-sm font-black"
                      >
                        -
                      </button>
                      <span className="min-w-8 text-center text-sm font-black">{item.quantity}</span>
                      <button
                        type="button"
                        onClick={() => updateQuantity(item.id, item.quantity + 1)}
                        className="inline-flex h-8 w-8 items-center justify-center rounded-full border border-slate-200 bg-white text-sm font-black"
                      >
                        +
                      </button>
                    </div>
                  </div>
                  <p className="text-lg font-black text-slate-900">
                    {formatCurrency(item.unitPrice * item.quantity)}
                  </p>
                </div>
              </article>
            ))}
          </div>
        </section>

        <aside className="rounded-[2rem] bg-white p-5 shadow-[0_14px_40px_rgba(15,23,42,0.06)]">
          <p className="text-xs font-black uppercase tracking-[0.2em] text-slate-400">Fechamento</p>

          {(storefront?.activePromotions?.length ?? 0) > 0 ? (
            <div className="mt-4 rounded-[1.3rem] bg-emerald-50 px-4 py-4">
              <p className="text-sm font-black text-emerald-800">
                {storefront?.activePromotions?.[0]?.title}
              </p>
              {storefront?.activePromotions?.[0]?.description ? (
                <p className="mt-1 text-sm text-emerald-700">
                  {storefront.activePromotions[0].description}
                </p>
              ) : null}
            </div>
          ) : null}

          <div className="mt-4 rounded-[1.3rem] border border-slate-200 bg-slate-50 p-4">
            <label className="grid gap-2">
              <span className="text-sm font-black text-slate-900">Cupom</span>
              <div className="flex gap-2">
                <input
                  value={couponCode}
                  onChange={(event) => updateState(items, event.target.value.toUpperCase(), { ...values, couponCode: event.target.value.toUpperCase() })}
                  placeholder="Digite o cupom"
                  className="h-11 flex-1 rounded-[1rem] border border-slate-200 bg-white px-4 text-sm outline-none"
                />
              </div>
            </label>
            {storefront?.activeCoupons?.length ? (
              <div className="mt-3 flex flex-wrap gap-2">
                {storefront.activeCoupons.slice(0, 3).map((coupon) => (
                  <button
                    key={coupon.id}
                    type="button"
                    onClick={() => updateState(items, coupon.code, { ...values, couponCode: coupon.code })}
                    className="rounded-full border border-slate-200 bg-white px-3 py-1 text-[10px] font-black uppercase tracking-[0.16em] text-slate-700"
                  >
                    {coupon.code}
                  </button>
                ))}
              </div>
            ) : null}
          </div>

          <div className="mt-4 space-y-3 rounded-[1.3rem] border border-slate-200 bg-slate-50 p-4 text-sm text-slate-700">
            <div className="flex items-center justify-between">
              <span>Subtotal</span>
              <strong>{formatCurrency(pricing.subtotal)}</strong>
            </div>
            <div className="flex items-center justify-between">
              <span>Entrega</span>
              <strong>{formatCurrency(pricing.deliveryFee)}</strong>
            </div>
            {pricing.promotionDiscount > 0 ? (
              <div className="flex items-center justify-between text-emerald-700">
                <span>Promocao</span>
                <strong>- {formatCurrency(pricing.promotionDiscount)}</strong>
              </div>
            ) : null}
            {pricing.couponDiscount > 0 ? (
              <div className="flex items-center justify-between text-emerald-700">
                <span>Cupom</span>
                <strong>- {formatCurrency(pricing.couponDiscount)}</strong>
              </div>
            ) : null}
          </div>

          <div className="mt-4 flex items-center justify-between border-t border-slate-200 pt-4">
            <span className="text-sm font-semibold text-slate-600">Total</span>
            <strong className="text-2xl font-black text-slate-950">{formatCurrency(pricing.total)}</strong>
          </div>

          <div className="mt-6 rounded-[1.4rem] border border-slate-200 bg-slate-50 p-4">
            <div className="flex items-center justify-between gap-3">
              <div>
                <p className="text-sm font-black text-slate-900">Entrega e pagamento</p>
                <p className="mt-1 text-xs text-slate-500">Tudo aqui, sem precisar andar por mais telas.</p>
              </div>
              <span className="rounded-full bg-white px-3 py-1 text-xs font-black text-slate-700">{completion}% pronto</span>
            </div>

            <div className="mt-4 grid gap-3 md:grid-cols-2">
              {[
                ['fullName', 'Cliente'],
                ['phone', 'Telefone'],
                ['email', 'Email'],
                ['street', 'Rua'],
                ['number', 'Numero'],
                ['complement', 'Complemento'],
                ['neighborhood', 'Bairro'],
                ['city', 'Cidade'],
                ['state', 'Estado'],
              ].map(([key, label]) => (
                <label key={key} className="grid gap-2">
                  <span className="text-[11px] font-black uppercase tracking-[0.18em] text-slate-500">{label}</span>
                  <input
                    value={values[key as keyof CheckoutProfile] as string}
                    onChange={handleChange(key as keyof CheckoutProfile)}
                    className="h-11 rounded-[1rem] border border-slate-200 bg-white px-4 text-sm outline-none"
                  />
                </label>
              ))}
              <label className="grid gap-2 md:col-span-2">
                <span className="text-[11px] font-black uppercase tracking-[0.18em] text-slate-500">CEP</span>
                <div className="flex gap-2">
                  <input value={values.zipCode} onChange={handleChange('zipCode')} className="h-11 flex-1 rounded-[1rem] border border-slate-200 bg-white px-4 text-sm outline-none" />
                  <button type="button" onClick={() => void handleLookupCep()} className="rounded-[1rem] bg-slate-950 px-4 text-xs font-black uppercase tracking-[0.18em] text-white">
                    {lookingUpCep ? 'Buscando...' : 'Buscar CEP'}
                  </button>
                </div>
              </label>
              <label className="grid gap-2 md:col-span-2">
                <span className="text-[11px] font-black uppercase tracking-[0.18em] text-slate-500">Observacoes</span>
                <textarea value={values.notes} onChange={handleChange('notes')} className="min-h-24 rounded-[1rem] border border-slate-200 bg-white px-4 py-3 text-sm outline-none" />
              </label>
            </div>
            {cepError ? <p className="mt-3 rounded-[1rem] border border-amber-200 bg-amber-50 px-4 py-3 text-sm text-amber-800">{cepError}</p> : null}

            <div className="mt-4">
              <p className="text-[11px] font-black uppercase tracking-[0.18em] text-slate-500">Metodo de pagamento</p>
              <div className="mt-3 grid gap-3">
                {paymentMethods.map(([value, method]) => (
                  <button
                    key={value}
                    type="button"
                    onClick={() => updateState(items, couponCode, { ...values, paymentMethod: value })}
                    className={`w-full rounded-[1.2rem] border px-4 py-3 text-left ${values.paymentMethod === value ? 'border-slate-950 bg-slate-950 text-white' : 'border-slate-200 bg-white text-slate-900'}`}
                  >
                    <p className="text-sm font-black">{method}</p>
                  </button>
                ))}
              </div>
            </div>
          </div>

          {currentIntent?.pix ? (
            <div className="mt-6 rounded-[1.4rem] border border-slate-200 bg-slate-50 p-4">
              <div className="flex flex-col gap-4 lg:flex-row lg:items-center">
                {currentIntent.pix.qrCodeImageUrl ? (
                  <div className="overflow-hidden rounded-[1.2rem] border border-slate-200 bg-white p-3">
                    <Image src={currentIntent.pix.qrCodeImageUrl} alt="QR Code PIX" width={160} height={160} className="h-auto w-[160px]" unoptimized />
                  </div>
                ) : null}
                <div className="min-w-0 flex-1">
                  <p className="text-sm font-black text-slate-900">PIX pronto</p>
                  <p className="mt-1 text-xs text-slate-500">Copie o codigo ou siga direto para criar o pedido.</p>
                  <div className="mt-3 break-all rounded-[1rem] bg-slate-950 px-4 py-3 text-xs text-slate-100">
                    {currentIntent.pix.qrCodeText}
                  </div>
                  <button type="button" onClick={() => void copyPixCode()} className="mt-3 rounded-full border border-slate-950 bg-slate-950 px-4 py-2 text-xs font-black uppercase tracking-[0.18em] text-white">
                    {copied ? 'Codigo copiado' : 'Copiar codigo PIX'}
                  </button>
                </div>
              </div>
            </div>
          ) : null}

          {error ? <p className="mt-4 rounded-[1rem] border border-rose-200 bg-rose-50 px-4 py-3 text-sm text-rose-700">{error}</p> : null}

          <div className="mt-6 flex flex-col gap-3">
            <button
              type="button"
              onClick={() => void submit()}
              disabled={submitting || intentLoading}
              className="inline-flex min-h-[3rem] items-center justify-center rounded-full bg-slate-950 px-4 text-xs font-black uppercase tracking-[0.18em] text-white disabled:opacity-60"
            >
              {submitting ? 'Criando pedido...' : 'Finalizar pedido aqui'}
            </button>
            <Link
              href="/public-order"
              className="inline-flex min-h-[3rem] items-center justify-center rounded-full border border-slate-200 bg-white px-4 text-xs font-black uppercase tracking-[0.18em] text-slate-800"
            >
              Adicionar mais itens
            </Link>
            <div className="grid gap-3 sm:grid-cols-2">
              <Link
                href="/public-order/checkout"
                className="inline-flex min-h-[3rem] items-center justify-center rounded-full border border-slate-200 bg-white px-4 text-[11px] font-black uppercase tracking-[0.18em] text-slate-700"
              >
                Checkout detalhado
              </Link>
              <Link
                href="/public-order/payment"
                className="inline-flex min-h-[3rem] items-center justify-center rounded-full border border-slate-200 bg-white px-4 text-[11px] font-black uppercase tracking-[0.18em] text-slate-700"
              >
                Tela de pagamento
              </Link>
            </div>
          </div>
        </aside>
      </div>
    </main>
  );
}
