import { useEffect, useMemo, useRef, useState } from "react";
import { Separator } from "@/components/ui/separator";
import { useNavigate } from "react-router-dom";
import { Eye, EyeOff, Loader2, RefreshCw, Save } from "lucide-react";
import { toast } from "sonner";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { MagicCard } from "@/components/ui/magic-card";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { Label } from "@/components/ui/label";
import { Badge } from "@/components/ui/badge";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { asanaService, type AsanaWorkspace } from "@/services/asana";
import {
  fechamentoConfiguracoesService,
  type ConfiguracaoPublica,
} from "@/services/fechamento/configuracoes";
import { fechamentoUnidadesService } from "@/services/fechamento/unidades";
import {
  clearCommanderUnidadeIdCache,
  getEstabelecimentoCodigoFromTransfer,
  lookupUnidadeByEstabelecimento,
  type UnidadeLookupRow,
} from "@/services/fechamento/unidadeContext";
import { useAuthAccess } from "@/contexts/AuthAccessContext";

export default function Configuracoes() {
  const navigate = useNavigate();
  const { papel } = useAuthAccess();
  const isAdmin = papel === "admin";
  const unidadeSectionRef = useRef<HTMLDivElement>(null);

  const [loading, setLoading] = useState(true);
  const [configAsanaError, setConfigAsanaError] = useState<string | null>(null);
  const [saving, setSaving] = useState(false);
  const [loadingWorkspaces, setLoadingWorkspaces] = useState(false);
  const [showToken, setShowToken] = useState(false);

  const [configAtual, setConfigAtual] = useState<ConfiguracaoPublica | null>(null);
  const [asanaToken, setAsanaToken] = useState("");
  const [workspaces, setWorkspaces] = useState<AsanaWorkspace[]>([]);
  const [selectedWorkspaceId, setSelectedWorkspaceId] = useState("");
  const [selectedWorkspaceNome, setSelectedWorkspaceNome] = useState("");

  const [codigoEstabelecimento, setCodigoEstabelecimento] = useState("");
  const [unidadeExistente, setUnidadeExistente] = useState<UnidadeLookupRow | null>(null);
  const [nomeUnidade, setNomeUnidade] = useState("");
  const [loadingUnidade, setLoadingUnidade] = useState(true);
  const [savingUnidade, setSavingUnidade] = useState(false);

  const tokenJaConfigurado = Boolean(configAtual?.asanaTokenConfigured);
  const tokenDigitado = asanaToken.trim();
  const podeBuscarWorkspaces = tokenDigitado.length >= 5 && !loadingWorkspaces;

  const workspaceOptions = useMemo(() => {
    if (!selectedWorkspaceId || !selectedWorkspaceNome) {
      return workspaces;
    }
    if (workspaces.some((item) => item.id === selectedWorkspaceId)) {
      return workspaces;
    }
    return [{ id: selectedWorkspaceId, name: selectedWorkspaceNome }, ...workspaces];
  }, [workspaces, selectedWorkspaceId, selectedWorkspaceNome]);

  const loadUnidade = async () => {
    try {
      setLoadingUnidade(true);
      const codigo = getEstabelecimentoCodigoFromTransfer();
      setCodigoEstabelecimento(codigo);
      if (!codigo) {
        setUnidadeExistente(null);
        setNomeUnidade("");
        return;
      }
      const row = await lookupUnidadeByEstabelecimento(codigo);
      setUnidadeExistente(row);
      setNomeUnidade(row?.nome ?? "");
    } catch {
      setUnidadeExistente(null);
      setNomeUnidade("");
    } finally {
      setLoadingUnidade(false);
    }
  };

  const loadConfiguracoesAsana = async () => {
    try {
      setConfigAsanaError(null);
      const data = await fechamentoConfiguracoesService.getConfiguracoes();
      setConfigAtual(data);
      setAsanaToken(data?.asanaToken ?? "");
      setSelectedWorkspaceId(data?.asanaWorkspaceId ?? "");
      setSelectedWorkspaceNome(data?.asanaWorkspaceNome ?? "");
    } catch (error) {
      const message = error instanceof Error ? error.message : "Erro ao carregar configurações do Asana.";
      setConfigAsanaError(message);
      setConfigAtual(null);
    }
  };

  const loadAll = async () => {
    try {
      setLoading(true);
      await Promise.all([loadUnidade(), loadConfiguracoesAsana()]);
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    void loadAll();
  }, []);

  useEffect(() => {
    if (typeof window === "undefined" || loading) return;
    if (window.location.hash === "#unidade" && unidadeSectionRef.current) {
      unidadeSectionRef.current.scrollIntoView({ behavior: "smooth", block: "start" });
    }
  }, [loading]);

  const handleBuscarWorkspaces = async () => {
    if (!tokenDigitado) {
      toast.error("Informe o token do Asana para buscar workspaces.");
      return;
    }

    try {
      setLoadingWorkspaces(true);
      const ws = await asanaService.getWorkspaces(tokenDigitado);
      setWorkspaces(ws);
      if (ws.length === 0) {
        toast.warning("Nenhum workspace foi encontrado para este token.");
        return;
      }

      if (selectedWorkspaceId && ws.some((item) => item.id === selectedWorkspaceId)) {
        const selected = ws.find((item) => item.id === selectedWorkspaceId);
        setSelectedWorkspaceNome(selected?.name ?? selectedWorkspaceNome);
      } else {
        setSelectedWorkspaceId("");
        setSelectedWorkspaceNome("");
      }

      toast.success(`${ws.length} workspace(s) carregado(s).`);
    } catch (error) {
      const message = error && typeof error === "object" && "message" in error
        ? String((error as { message: unknown }).message)
        : "Erro ao buscar workspaces do Asana.";
      toast.error(message);
      setWorkspaces([]);
    } finally {
      setLoadingWorkspaces(false);
    }
  };

  const handleSaveAsana = async () => {
    if (!selectedWorkspaceId) {
      toast.error("Selecione um workspace antes de salvar.");
      return;
    }

    try {
      setSaving(true);
      const workspaceSelecionado = workspaceOptions.find((item) => item.id === selectedWorkspaceId);
      const updated = await fechamentoConfiguracoesService.salvarConfiguracoes({
        asanaToken: tokenDigitado ? tokenDigitado : undefined,
        asanaWorkspaceId: selectedWorkspaceId,
        asanaWorkspaceNome: workspaceSelecionado?.name ?? selectedWorkspaceNome,
      });

      setConfigAtual(updated);
      setAsanaToken(updated.asanaToken ?? "");
      setSelectedWorkspaceId(updated.asanaWorkspaceId ?? "");
      setSelectedWorkspaceNome(updated.asanaWorkspaceNome ?? "");
      setConfigAsanaError(null);
      toast.success("Configurações salvas com sucesso.");
    } catch (error) {
      const message = error instanceof Error ? error.message : "Erro ao salvar configurações.";
      toast.error(message);
    } finally {
      setSaving(false);
    }
  };

  const handleSalvarUnidade = async () => {
    const nome = nomeUnidade.trim();
    if (!nome) {
      toast.error("Informe o nome da unidade.");
      return;
    }
    const codigo = codigoEstabelecimento.trim();
    if (!codigo) {
      toast.error("Código do estabelecimento não disponível no transfer.");
      return;
    }

    try {
      setSavingUnidade(true);
      if (unidadeExistente) {
        await fechamentoUnidadesService.updateUnidade(unidadeExistente.id, { nome });
        toast.success("Unidade atualizada.");
        clearCommanderUnidadeIdCache();
        await loadUnidade();
      } else {
        await fechamentoUnidadesService.createUnidade({ nome, estabelecimentoId: codigo });
        toast.success("Unidade cadastrada.");
        clearCommanderUnidadeIdCache();
        navigate("/fechamento", { replace: true });
      }
    } catch (error) {
      const message = error instanceof Error ? error.message : "Erro ao salvar unidade.";
      toast.error(message);
    } finally {
      setSavingUnidade(false);
    }
  };

  if (loading) {
    return (
      <div className="flex min-h-[300px] items-center justify-center">
        <div className="flex items-center gap-3 text-muted-foreground">
          <Loader2 className="h-5 w-5 animate-spin" />
          <span>Carregando configurações...</span>
        </div>
      </div>
    );
  }

  return (
    <div className="mx-auto w-full max-w-5xl space-y-8 pb-8">
      <header className="border-b border-border pb-6">
        <h1 className="text-xl font-semibold tracking-tight text-foreground md:text-2xl">Configurações do sistema</h1>
        <p className="mt-1 max-w-3xl text-sm leading-relaxed text-muted-foreground">
          Cadastro da unidade (estabelecimento) e integração com o Asana. Alterações aplicam-se ao contexto
          atual do Commander.
        </p>
      </header>

      <div ref={unidadeSectionRef} id="unidade">
        <Card className="overflow-hidden border-border bg-card p-0 text-card-foreground shadow-sm">
          <MagicCard
            className="rounded-lg"
            gradientFrom="hsl(var(--primary))"
            gradientTo="hsl(var(--secondary))"
            gradientSize={220}
          >
            <CardHeader className="space-y-0 border-b bg-muted/30 px-6 py-4">
              <CardTitle id="titulo-codigo-estabelecimento" className="text-base font-semibold">
                Código do estabelecimento
              </CardTitle>
            </CardHeader>
            <CardContent className="space-y-5 px-6 py-6">
            {loadingUnidade ? (
              <div className="flex items-center gap-2 text-sm text-muted-foreground">
                <Loader2 className="h-4 w-4 animate-spin" />
                Carregando dados da unidade...
              </div>
            ) : !isAdmin ? (
              <p className="text-sm text-muted-foreground">
                Apenas administradores podem cadastrar ou editar a unidade aqui.
              </p>
            ) : !codigoEstabelecimento ? (
              <p className="text-sm text-muted-foreground">
                Abra o módulo pelo Codex com o estabelecimento no transfer para exibir o código e cadastrar a
                unidade.
              </p>
            ) : (
              <>
                <div className="space-y-2">
                  <Input
                    id="codigo-estabelecimento"
                    aria-labelledby="titulo-codigo-estabelecimento"
                    value={codigoEstabelecimento}
                    readOnly
                    className="h-11 font-mono text-sm bg-muted"
                  />
                </div>
                <div className="space-y-2">
                  <Label htmlFor="nome-unidade">Nome da unidade</Label>
                  <Input
                    id="nome-unidade"
                    value={nomeUnidade}
                    onChange={(e) => setNomeUnidade(e.target.value)}
                    placeholder="Ex.: Unidade Matriz"
                    className="h-11 text-sm"
                  />
                </div>
                <div className="flex flex-wrap items-center gap-2">
                  {unidadeExistente ? (
                    <Badge variant="secondary" className="shrink-0 whitespace-nowrap">
                      Unidade cadastrada
                    </Badge>
                  ) : (
                    <Badge variant="outline" className="max-w-full shrink-0 whitespace-normal sm:whitespace-nowrap">
                      Pendente: informe o nome e salve para criar a unidade
                    </Badge>
                  )}
                </div>
                <div className="flex justify-end border-t border-border pt-4">
                  <Button type="button" onClick={handleSalvarUnidade} disabled={savingUnidade}>
                    {savingUnidade ? (
                      <>
                        <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                        Salvando...
                      </>
                    ) : (
                      <>
                        <Save className="mr-2 h-4 w-4" />
                        {unidadeExistente ? "Salvar nome da unidade" : "Criar unidade"}
                      </>
                    )}
                  </Button>
                </div>
              </>
            )}
          </CardContent>
          </MagicCard>
        </Card>
      </div>

      <Separator className="opacity-60" />

      <Card className="overflow-hidden border-border bg-card p-0 text-card-foreground shadow-sm">
        <MagicCard
          className="rounded-lg"
          gradientFrom="hsl(var(--primary))"
          gradientTo="hsl(var(--secondary))"
          gradientSize={220}
        >
          <CardHeader className="space-y-1 border-b bg-muted/30 px-6 py-4">
            <CardTitle className="text-base font-semibold">Integração Asana</CardTitle>
            <CardDescription className="text-sm leading-relaxed">
              Token pessoal ou de serviço, listagem de workspaces e workspace padrão usado nas importações.
            </CardDescription>
          </CardHeader>
          <CardContent className="space-y-6 px-6 py-6">
          {configAsanaError ? (
            <div
              role="alert"
              className="rounded-md border border-destructive/40 bg-destructive/5 px-4 py-3 text-sm text-destructive"
            >
              <p className="font-medium">Não foi possível carregar as configurações do Asana</p>
              <p className="mt-1 leading-relaxed opacity-90">
                {configAsanaError} Cadastre a unidade acima, se necessário, e atualize a página.
              </p>
            </div>
          ) : null}
          <div className="space-y-3">
            <div className="flex flex-col gap-1 sm:flex-row sm:items-center sm:justify-between">
              <Label htmlFor="asana-token" className="text-sm font-medium">
                Token de acesso
              </Label>
              <div className="flex w-full justify-start sm:w-auto sm:justify-end">
                {tokenJaConfigurado ? (
                  <Badge variant="secondary" className="shrink-0 whitespace-nowrap">
                    Token configurado no servidor
                  </Badge>
                ) : (
                  <Badge variant="outline" className="shrink-0 whitespace-nowrap">
                    Token ainda não salvo
                  </Badge>
                )}
              </div>
            </div>
            <div className="flex flex-col gap-3 lg:flex-row lg:items-stretch">
              <div className="relative min-w-0 flex-1">
                <Input
                  id="asana-token"
                  type={showToken ? "text" : "password"}
                  value={asanaToken}
                  onChange={(e) => setAsanaToken(e.target.value)}
                  placeholder={
                    tokenJaConfigurado
                      ? "Substitua o token ou mantenha em branco para não alterar ao salvar"
                      : "Cole o token do Asana (Personal Access Token)"
                  }
                  className="h-11 pr-11 font-mono text-sm"
                  disabled={Boolean(configAsanaError)}
                  autoComplete="off"
                />
                <button
                  type="button"
                  onClick={() => setShowToken((prev) => !prev)}
                  title={showToken ? "Ocultar token" : "Mostrar token"}
                  className="absolute right-2 top-1/2 flex h-8 w-8 -translate-y-1/2 items-center justify-center rounded-md text-muted-foreground hover:bg-muted hover:text-foreground"
                >
                  {showToken ? <EyeOff className="h-4 w-4" /> : <Eye className="h-4 w-4" />}
                </button>
              </div>
              <Button
                type="button"
                variant="secondary"
                className="h-11 shrink-0 whitespace-nowrap px-5 lg:self-stretch"
                onClick={handleBuscarWorkspaces}
                disabled={!podeBuscarWorkspaces || Boolean(configAsanaError)}
              >
                {loadingWorkspaces ? (
                  <>
                    <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                    Buscando…
                  </>
                ) : (
                  <>
                    <RefreshCw className="mr-2 h-4 w-4" />
                    Listar workspaces
                  </>
                )}
              </Button>
            </div>
          </div>

          <div className="space-y-3">
            <Label htmlFor="asana-workspace" className="text-sm font-medium">
              Workspace padrão
            </Label>
            <Select
              value={selectedWorkspaceId}
              onValueChange={(value) => {
                setSelectedWorkspaceId(value);
                const selected = workspaceOptions.find((item) => item.id === value);
                setSelectedWorkspaceNome(selected?.name ?? "");
              }}
              disabled={Boolean(configAsanaError)}
            >
              <SelectTrigger id="asana-workspace" className="h-11 w-full">
                <SelectValue
                  placeholder={
                    workspaceOptions.length > 0
                      ? "Selecione um workspace"
                      : "Informe o token e clique em Listar workspaces"
                  }
                />
              </SelectTrigger>
              <SelectContent>
                {workspaceOptions.map((workspace) => (
                  <SelectItem key={workspace.id} value={workspace.id}>
                    {workspace.name}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
            <p className="text-xs leading-relaxed text-muted-foreground">
              Selecionado: <span className="font-medium text-foreground">{selectedWorkspaceNome || "—"}</span>
            </p>
          </div>

          <div className="flex justify-end border-t border-border pt-4">
            <Button
              type="button"
              size="lg"
              className="min-w-[200px]"
              onClick={handleSaveAsana}
              disabled={saving || !selectedWorkspaceId || Boolean(configAsanaError)}
            >
              {saving ? (
                <>
                  <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                  Salvando…
                </>
              ) : (
                <>
                  <Save className="mr-2 h-4 w-4" />
                  Salvar integração Asana
                </>
              )}
            </Button>
          </div>
        </CardContent>
        </MagicCard>
      </Card>
    </div>
  );
}
