import AdminLayout from "@/components/AdminLayout";
import FileUploadField from "@/components/admin/FileUploadField";
import { Button } from "@/components/ui/button";
import {
  Dialog,
  DialogContent,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { Switch } from "@/components/ui/switch";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { Textarea } from "@/components/ui/textarea";
import { trpc } from "@/lib/trpc";
import { assetUrl } from "@/lib/asset";
import type { MusicaFaixa } from "@shared/types";
import { useEffect, useState } from "react";
import { toast } from "sonner";

const NONE = "none";

type FaixaForm = {
  titulo: string;
  slug: string;
  descricao: string;
  arquivo: string;
  capa: string;
  duracao: string;
  numeroFaixa: string;
  ordem: string;
  letra: string;
  tags: string;
  artistaId: string;
  albumId: string;
  status: "rascunho" | "publicado" | "agendado";
  ativo: boolean;
};

const emptyForm: FaixaForm = {
  titulo: "",
  slug: "",
  descricao: "",
  arquivo: "",
  capa: "",
  duracao: "",
  numeroFaixa: "",
  ordem: "",
  letra: "",
  tags: "",
  artistaId: NONE,
  albumId: NONE,
  status: "publicado",
  ativo: true,
};

/**
 * Detecta a duração real do arquivo de áudio no navegador — mesmo mecanismo
 * que o Player usa (evento loadedmetadata do <audio>). Evita digitar a
 * duração manualmente a cada faixa.
 */
function detectarDuracao(url: string, onDetected: (segundos: number) => void) {
  const src = assetUrl(url);
  if (!src) return;

  const audio = new Audio();
  audio.preload = "metadata";
  audio.addEventListener("loadedmetadata", () => {
    if (isFinite(audio.duration) && audio.duration > 0) {
      onDetected(Math.round(audio.duration));
    }
  });
  audio.addEventListener("error", () => {
    // Falha silenciosa — o campo de duração continua editável manualmente.
  });
  audio.src = src;
}

function toForm(fx: MusicaFaixa): FaixaForm {
  return {
    titulo: fx.titulo,
    slug: fx.slug ?? "",
    descricao: fx.descricao ?? "",
    arquivo: fx.arquivo ?? "",
    capa: fx.capa ?? "",
    duracao: fx.duracao != null ? String(fx.duracao) : "",
    numeroFaixa: fx.numeroFaixa != null ? String(fx.numeroFaixa) : "",
    ordem: fx.ordem != null ? String(fx.ordem) : "",
    letra: fx.letra ?? "",
    tags: fx.tags ?? "",
    artistaId: fx.artistaId != null ? String(fx.artistaId) : NONE,
    albumId: fx.albumId != null ? String(fx.albumId) : NONE,
    status: fx.status ?? "publicado",
    ativo: fx.ativo === 1,
  };
}

export default function AdminMusicaFaixas() {
  const [page, setPage] = useState(1);
  const [dialogOpen, setDialogOpen] = useState(false);
  const [editing, setEditing] = useState<MusicaFaixa | null>(null);
  const [form, setForm] = useState<FaixaForm>(emptyForm);

  const utils = trpc.useUtils();
  const { data, isLoading } = trpc.musica.admin.faixas.listar.useQuery({ page, limit: 20 });
  const artistasQuery = trpc.musica.admin.artistas.listar.useQuery(
    { page: 1, limit: 60 },
    { onError: error => toast.error(`Erro ao carregar artistas: ${error.message}`) }
  );
  const albunsQuery = trpc.musica.admin.albuns.listar.useQuery(
    { page: 1, limit: 60 },
    { onError: error => toast.error(`Erro ao carregar álbuns: ${error.message}`) }
  );

  const invalidate = () => {
    utils.musica.admin.faixas.listar.invalidate();
  };

  const criarMutation = trpc.musica.admin.faixas.criar.useMutation({
    onSuccess: () => {
      toast.success("Faixa criada.");
      invalidate();
      setDialogOpen(false);
    },
    onError: error => toast.error(error.message),
  });

  const atualizarMutation = trpc.musica.admin.faixas.atualizar.useMutation({
    onSuccess: () => {
      toast.success("Faixa atualizada.");
      invalidate();
      setDialogOpen(false);
    },
    onError: error => toast.error(error.message),
  });

  const deletarMutation = trpc.musica.admin.faixas.deletar.useMutation({
    onSuccess: () => {
      toast.success("Faixa removida.");
      invalidate();
    },
    onError: error => toast.error(error.message),
  });

  useEffect(() => {
    if (!dialogOpen) {
      setEditing(null);
      setForm(emptyForm);
    }
  }, [dialogOpen]);

  const handleEdit = (fx: MusicaFaixa) => {
    setEditing(fx);
    setForm(toForm(fx));
    setDialogOpen(true);
  };

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();

    if (!form.arquivo.trim()) {
      toast.error("Faça o upload do arquivo de áudio.");
      return;
    }

    const payload = {
      titulo: form.titulo.trim(),
      slug: form.slug.trim() || undefined,
      descricao: form.descricao.trim() || null,
      arquivo: form.arquivo.trim() || null,
      capa: form.capa.trim() || null,
      duracao: form.duracao ? Number(form.duracao) : null,
      numeroFaixa: form.numeroFaixa ? Number(form.numeroFaixa) : null,
      ordem: form.ordem ? Number(form.ordem) : null,
      letra: form.letra.trim() || null,
      tags: form.tags.trim() || null,
      artistaId: form.artistaId === NONE ? null : Number(form.artistaId),
      albumId: form.albumId === NONE ? null : Number(form.albumId),
      status: form.status,
      ativo: form.ativo ? 1 : 0,
    };

    if (editing) {
      atualizarMutation.mutate({ id: editing.id, ...payload });
    } else {
      criarMutation.mutate(payload);
    }
  };

  const handleDelete = (fx: MusicaFaixa) => {
    if (!window.confirm(`Excluir a faixa "${fx.titulo}"? Esta ação não pode ser desfeita.`)) return;
    deletarMutation.mutate({ id: fx.id });
  };

  const isSaving = criarMutation.isPending || atualizarMutation.isPending;

  // Álbuns filtrados pelo artista selecionado (se houver), para reduzir erro de cadastro
  const albunsFiltrados =
    form.artistaId === NONE
      ? albunsQuery.data?.albuns
      : albunsQuery.data?.albuns.filter(al => al.artistaId === Number(form.artistaId));

  return (
    <AdminLayout>
      <div className="p-6 space-y-6">
        <div className="flex items-center justify-between">
          <div>
            <h1 className="text-2xl font-bold font-display text-sof-gold">Faixas</h1>
            <p className="text-sm text-sof-text-3 mt-1">{data?.total ?? 0} faixas cadastradas</p>
          </div>
          <Button
            onClick={() => setDialogOpen(true)}
            className="bg-sof-gold text-sof-borgonha hover:bg-sof-gold-light font-bold"
          >
            + Nova Faixa
          </Button>
        </div>

        {isLoading ? (
          <p className="text-sof-text-3">Carregando...</p>
        ) : (
          <Table>
            <TableHeader>
              <TableRow className="border-sof-border">
                <TableHead className="text-sof-text-3">Título</TableHead>
                <TableHead className="text-sof-text-3">Artista</TableHead>
                <TableHead className="text-sof-text-3">Álbum</TableHead>
                <TableHead className="text-sof-text-3">Status</TableHead>
                <TableHead className="text-sof-text-3">Ativo</TableHead>
                <TableHead className="text-sof-text-3 text-right">Ações</TableHead>
              </TableRow>
            </TableHeader>
            <TableBody>
              {data?.faixas.length ? (
                data.faixas.map(fx => (
                  <TableRow key={fx.id} className="border-sof-border hover:bg-sof-surface">
                    <TableCell className="text-sof-text font-medium max-w-xs truncate">{fx.titulo}</TableCell>
                    <TableCell className="text-sof-text-3 text-sm">
                      {artistasQuery.data?.artistas.find(a => a.id === fx.artistaId)?.nome ?? "—"}
                    </TableCell>
                    <TableCell className="text-sof-text-3 text-sm">
                      {albunsQuery.data?.albuns.find(al => al.id === fx.albumId)?.titulo ?? "—"}
                    </TableCell>
                    <TableCell className="text-sof-text-3 text-sm capitalize">{fx.status}</TableCell>
                    <TableCell className="text-sof-text-3 text-sm">{fx.ativo === 1 ? "✓" : "✗"}</TableCell>
                    <TableCell className="text-right">
                      <div className="flex justify-end gap-2">
                        <Button
                          size="sm"
                          variant="outline"
                          className="border-sof-border text-sof-text hover:bg-sof-surface"
                          onClick={() => handleEdit(fx)}
                        >
                          Editar
                        </Button>
                        <Button size="sm" variant="destructive" onClick={() => handleDelete(fx)}>
                          Excluir
                        </Button>
                      </div>
                    </TableCell>
                  </TableRow>
                ))
              ) : (
                <TableRow>
                  <TableCell colSpan={6} className="text-center text-sof-text-3">
                    Nenhuma faixa cadastrada.
                  </TableCell>
                </TableRow>
              )}
            </TableBody>
          </Table>
        )}

        {!!data && data.pages > 1 && (
          <div className="flex items-center justify-center gap-4 mt-6">
            <Button
              variant="outline"
              size="sm"
              disabled={page <= 1}
              onClick={() => setPage(p => p - 1)}
              className="border-sof-border text-sof-text hover:bg-sof-surface"
            >
              ← Anterior
            </Button>
            <span className="text-sm text-sof-text-3">
              Página {data.page} de {data.pages}
            </span>
            <Button
              variant="outline"
              size="sm"
              disabled={page >= data.pages}
              onClick={() => setPage(p => p + 1)}
              className="border-sof-border text-sof-text hover:bg-sof-surface"
            >
              Próxima →
            </Button>
          </div>
        )}

        <Dialog open={dialogOpen} onOpenChange={setDialogOpen}>
          <DialogContent className="max-w-2xl max-h-[90vh] overflow-y-auto">
            <DialogHeader>
              <DialogTitle>{editing ? "Editar faixa" : "Nova faixa"}</DialogTitle>
            </DialogHeader>

            <div className="space-y-4">
              <div className="grid grid-cols-2 gap-4">
                <div className="col-span-2 space-y-2">
                  <Label>Título *</Label>
                  <Input required value={form.titulo} onChange={e => setForm(f => ({ ...f, titulo: e.target.value }))} />
                </div>

                <div className="space-y-2">
                  <Label>Slug</Label>
                  <Input
                    value={form.slug}
                    onChange={e => setForm(f => ({ ...f, slug: e.target.value }))}
                    placeholder="gerado automaticamente se vazio"
                  />
                </div>

                <div className="space-y-2">
                  <Label>Status</Label>
                  <Select value={form.status} onValueChange={v => setForm(f => ({ ...f, status: v as FaixaForm["status"] }))}>
                    <SelectTrigger className="w-full">
                      <SelectValue />
                    </SelectTrigger>
                    <SelectContent>
                      <SelectItem value="publicado">Publicado</SelectItem>
                      <SelectItem value="rascunho">Rascunho</SelectItem>
                      <SelectItem value="agendado">Agendado</SelectItem>
                    </SelectContent>
                  </Select>
                </div>

                <div className="col-span-2 space-y-2">
                  <Label>Descrição</Label>
                  <Textarea rows={3} value={form.descricao} onChange={e => setForm(f => ({ ...f, descricao: e.target.value }))} />
                </div>

                <div className="col-span-2">
                  <FileUploadField
                    label="Arquivo de áudio (MP3)"
                    type="audio"
                    value={form.arquivo}
                    onChange={url => {
                      setForm(f => ({ ...f, arquivo: url }));
                      if (url) {
                        detectarDuracao(url, segundos =>
                          setForm(f => ({ ...f, duracao: String(segundos) }))
                        );
                      }
                    }}
                  />
                </div>

                <div className="col-span-2">
                  <FileUploadField
                    label="Capa"
                    type="image"
                    value={form.capa}
                    onChange={url => setForm(f => ({ ...f, capa: url }))}
                  />
                </div>

                <div className="space-y-2">
                  <Label>Duração (segundos) — detectada automaticamente</Label>
                  <Input type="number" min={0} value={form.duracao} onChange={e => setForm(f => ({ ...f, duracao: e.target.value }))} />
                </div>

                <div className="space-y-2">
                  <Label>Número da faixa</Label>
                  <Input type="number" min={0} value={form.numeroFaixa} onChange={e => setForm(f => ({ ...f, numeroFaixa: e.target.value }))} />
                </div>

                <div className="space-y-2">
                  <Label>Artista</Label>
                  <Select
                    value={form.artistaId}
                    onValueChange={v => setForm(f => ({ ...f, artistaId: v, albumId: NONE }))}
                  >
                    <SelectTrigger className="w-full">
                      <SelectValue />
                    </SelectTrigger>
                    <SelectContent>
                      <SelectItem value={NONE}>Nenhum</SelectItem>
                      {artistasQuery.data?.artistas.map(a => (
                        <SelectItem key={a.id} value={String(a.id)}>
                          {a.nome}
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                </div>

                <div className="space-y-2">
                  <Label>Álbum</Label>
                  <Select value={form.albumId} onValueChange={v => setForm(f => ({ ...f, albumId: v }))}>
                    <SelectTrigger className="w-full">
                      <SelectValue />
                    </SelectTrigger>
                    <SelectContent>
                      <SelectItem value={NONE}>Nenhum</SelectItem>
                      {albunsFiltrados?.map(al => (
                        <SelectItem key={al.id} value={String(al.id)}>
                          {al.titulo}
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                </div>

                <div className="space-y-2">
                  <Label>Ordem</Label>
                  <Input type="number" value={form.ordem} onChange={e => setForm(f => ({ ...f, ordem: e.target.value }))} />
                </div>

                <div className="space-y-2">
                  <Label>Tags (separadas por vírgula)</Label>
                  <Input value={form.tags} onChange={e => setForm(f => ({ ...f, tags: e.target.value }))} />
                </div>

                <div className="col-span-2 space-y-2">
                  <Label>Letra</Label>
                  <Textarea rows={4} value={form.letra} onChange={e => setForm(f => ({ ...f, letra: e.target.value }))} />
                </div>

                <div className="col-span-2 flex items-center gap-3">
                  <Switch checked={form.ativo} onCheckedChange={checked => setForm(f => ({ ...f, ativo: checked }))} />
                  <Label>Ativo (visível no site)</Label>
                </div>
              </div>

              <DialogFooter>
                <Button
                  type="button"
                  variant="outline"
                  onClick={() => setDialogOpen(false)}
                  className="border-sof-border text-sof-text hover:bg-sof-surface"
                >
                  Cancelar
                </Button>
                <Button
                  onClick={handleSubmit}
                  disabled={isSaving}
                  className="bg-sof-gold text-sof-borgonha hover:bg-sof-gold-light font-bold"
                >
                  {isSaving ? "Salvando..." : "Salvar"}
                </Button>
              </DialogFooter>
            </div>
          </DialogContent>
        </Dialog>
      </div>
    </AdminLayout>
  );
}
