"use client";

import Link from "next/link";
import { Loader2, Lock, MonitorPlay } from "lucide-react";
import type { ReactNode } from "react";

/*
 * Peças comuns da área "Produtos digitais" do painel.
 */

export class ErroDaArea extends Error {
  readonly status: number;
  readonly motivo: string | null;
  constructor(mensagem: string, status: number, motivo: string | null) {
    super(mensagem);
    this.status = status;
    this.motivo = motivo;
  }
}

/* Pede JSON às rotas da área e traduz a recusa para um erro que a tela mostra. */
export async function pedirDigitais<T>(url: string, init?: RequestInit): Promise<T> {
  const resposta = await fetch(url, {
    ...init,
    headers: { "content-type": "application/json", ...(init?.headers ?? {}) },
    cache: "no-store",
  });
  const corpo = (await resposta.json().catch(() => null)) as (T & { error?: string; motivo?: string }) | null;
  if (!resposta.ok) {
    throw new ErroDaArea(
      corpo?.error || "Não foi possível carregar agora. Tente de novo em instantes.",
      resposta.status,
      typeof corpo?.motivo === "string" ? corpo.motivo : null
    );
  }
  return corpo as T;
}

/* A área ainda não liberada para a empresa, ou a pessoa sem permissão. */
export function AreaFechada({ erro }: { erro: ErroDaArea }) {
  const naoLiberada = erro.motivo === "nao_liberado";
  return (
    <div className="mx-auto flex max-w-lg flex-col items-center gap-4 px-6 py-16 text-center">
      <span
        className="flex h-14 w-14 items-center justify-center rounded-2xl text-white"
        style={{ background: "linear-gradient(135deg, var(--ks-brand-500) 0%, var(--ks-brand-700) 100%)", boxShadow: "0 10px 24px rgba(95, 49, 214, 0.28)" }}
      >
        {naoLiberada ? <MonitorPlay size={26} /> : <Lock size={24} />}
      </span>
      <h2 className="text-lg font-extrabold text-[var(--ks-color-text-primary)]">
        {naoLiberada ? "Produtos digitais chegam em breve" : "Esta parte não está aberta para você"}
      </h2>
      <p className="text-sm leading-relaxed text-[var(--ks-color-text-muted)]">
        {naoLiberada
          ? "A área de conteúdos em vídeo, arquivos e área de membros está sendo liberada aos poucos. Assim que chegar para a sua empresa, ela aparece no menu."
          : erro.message}
      </p>
      <Link href="/dashboard" className="ks-button ks-button-soft">
        Voltar ao início
      </Link>
    </div>
  );
}

export function CarregandoArea({ texto = "Carregando..." }: { texto?: string }) {
  return (
    <div className="flex items-center justify-center gap-2 py-20 text-sm text-[var(--ks-color-text-muted)]">
      <Loader2 className="h-4 w-4 animate-spin" />
      {texto}
    </div>
  );
}

/* Erro que não é de acesso: a tela continua, com o aviso no lugar do conteúdo. */
export function FalhaDaArea({ erro, aoTentarDeNovo }: { erro: Error; aoTentarDeNovo?: () => void }) {
  return (
    <div className="mx-auto flex max-w-md flex-col items-center gap-3 px-6 py-14 text-center">
      <p className="text-sm text-[var(--ks-color-text-muted)]">{erro.message}</p>
      {aoTentarDeNovo ? (
        <button type="button" onClick={aoTentarDeNovo} className="ks-button ks-button-soft">
          Tentar de novo
        </button>
      ) : null}
    </div>
  );
}

/* Um número grande com rótulo, para as faixas de números das telas. */
export function NumeroDaArea({ rotulo, valor, detalhe }: { rotulo: string; valor: ReactNode; detalhe?: ReactNode }) {
  return (
    <div className="min-w-0 px-5 py-4">
      <p className="text-[11px] font-bold uppercase tracking-[0.12em] text-[var(--ks-color-text-soft)]">{rotulo}</p>
      <p className="ks-num mt-1 truncate text-2xl font-extrabold tracking-tight text-[var(--ks-color-text-primary)]">{valor}</p>
      {detalhe ? <p className="mt-0.5 text-xs text-[var(--ks-color-text-muted)]">{detalhe}</p> : null}
    </div>
  );
}

export const moeda = (valor: number) =>
  new Intl.NumberFormat("pt-BR", { style: "currency", currency: "BRL" }).format(Number.isFinite(valor) ? valor : 0);
