"use client";

import { useState, useCallback, useMemo } from "react";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { toast } from "sonner";
import { Plus, MoreHorizontal, Loader2, Building2, Car, CreditCard, TrendingUp, Search, ChevronLeft, ChevronRight, Mail, Phone, MapPin, Users, Calendar, SearchCheck, ShieldCheck, ShieldOff, ArrowUpDown, FlaskConical, Receipt, Sparkles, KeyRound, SlidersHorizontal } from "lucide-react";
import { useRepositories } from "@/di/repository-provider";
import { useT, useLocale } from "@/shared/i18n/client";
import { formatDate } from "@/shared/lib/format-date";
import { useApiQuery } from "@/presentation/hooks/use-api-query";
import { useApiMutation } from "@/presentation/hooks/use-api-mutation";
import { useCrudMutations } from "@/presentation/hooks/use-crud-mutations";
import { useDeleteTarget } from "@/presentation/hooks/use-delete-target";
import { useServerPagination } from "@/presentation/hooks/use-server-pagination";
import { useAuth } from "@/presentation/hooks/use-auth";
import StatsCard from "@/presentation/components/shared/stats-card";
import ConfirmationDialog from "@/presentation/components/shared/confirmation-dialog";
import McpTokenDialog from "@/presentation/components/shared/mcp-token-dialog";
import { Button } from "@/presentation/components/ui/button";
import { Input } from "@/presentation/components/ui/input";
import { Badge } from "@/presentation/components/ui/badge";
import { Card, CardContent } from "@/presentation/components/ui/card";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/presentation/components/ui/select";
import { AccessStatusBadge } from "@/presentation/components/shared/status-badge";
import { Avatar, AvatarFallback, AvatarImage } from "@/presentation/components/ui/avatar";
import { Skeleton } from "@/presentation/components/ui/skeleton";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
} from "@/presentation/components/ui/dialog";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from "@/presentation/components/ui/dropdown-menu";
import {
  Form,
  FormControl,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from "@/presentation/components/ui/form";
import { createCompanySchema, type CreateCompanyFormValues } from "@/shared/schemas/company.schema";
import type { Company } from "@/domain/entities/company";
import { CompanyEntitlementsSheet } from "@/presentation/components/entitlements/company-entitlements-sheet";

export default function CompaniesPanel() {
  const t = useT();
  const locale = useLocale();
  const container = useRepositories();
  const { hasPermission } = useAuth();
  const canImpersonate = hasPermission("impersonate.use");
  const pagination = useServerPagination();
  const [dialogOpen, setDialogOpen] = useState(false);
  const [editingCompany, setEditingCompany] = useState<Company | null>(null);
  const deleteDialog = useDeleteTarget<Company>();
  const [mcpTokenTarget, setMcpTokenTarget] = useState<Company | null>(null);
  // SCRUM-353: the company whose plan and exceptions are open
  const canManagePlans = hasPermission("subscriptions.manage");
  const [entitlementsTarget, setEntitlementsTarget] = useState<Company | null>(null);

  const { data: stats } = useApiQuery(
    () => container.companyRepository.getStats(),
    { deps: [] }
  );

  const { data: response, loading, refetch } = useApiQuery(
    () => container.companyRepository.findAll(pagination.params),
    { deps: [pagination.params] }
  );

  const { create: createMutation, update: updateMutation, delete: deleteMutation } = useCrudMutations(
    container.companyRepository,
    {
      create: { successMessage: t.companies.toasts.created, onSuccess: () => { setDialogOpen(false); refetch(); } },
      update: { successMessage: t.companies.toasts.updated, onSuccess: () => { setDialogOpen(false); setEditingCompany(null); refetch(); } },
      delete: { successMessage: t.companies.toasts.deleted, onSuccess: () => { deleteDialog.close(); refetch(); } },
    }
  );

  const impersonateMutation = useApiMutation(
    (id: number) => container.companyRepository.impersonate(id),
    {
      onSuccess: (data) => {
        navigator.clipboard.writeText(data.token);
        toast.success(t.common.tokenCopied);
      },
    }
  );

  // Toggle is keyed off the server's current state (enabled → disables w/ cascade, disabled → enables).
  // Heavy but synchronous: button is disabled while loading to avoid double-submits; refetch syncs the badge.
  const toggleStatusMutation = useApiMutation(
    (id: number) => container.companyRepository.toggleStatus(id),
    {
      loadingMessage: t.companies.toasts.accessUpdating,
      onSuccess: (data) => {
        toast.success(data.access_status.enabled ? t.companies.toasts.accessEnabled : t.companies.toasts.accessDisabled);
        refetch();
      },
    }
  );

  // Test-account flag: flagged companies are excluded from the Customer Health
  // & Adoption statistics (dashboard, list, benchmark peers).
  const toggleTestMutation = useApiMutation(
    (id: number) => container.companyRepository.toggleTest(id),
    {
      onSuccess: (data) => {
        toast.success(data.is_test_account ? t.companies.toasts.testFlagged : t.companies.toasts.testUnflagged);
        refetch();
      },
    }
  );

  // SCRUM-315 — grant/revoke the inter-company refacturation feature for the company's group.
  // Revoking also switches the group's own toggle off (backend).
  const toggleRefacturationMutation = useApiMutation(
    (id: number) => container.companyRepository.toggleRefacturation(id),
    {
      onSuccess: (data) => {
        toast.success(data.feature_granted ? t.companies.toasts.refacturationGranted : t.companies.toasts.refacturationRevoked);
        refetch();
      },
    }
  );

  // Early access to Donna before the public release.
  const toggleAiAgentsMutation = useApiMutation(
    (id: number) => container.companyRepository.toggleAiAgents(id),
    {
      onSuccess: (data) => {
        toast.success(data.ai_agents_enabled ? t.companies.toasts.aiAgentsEnabled : t.companies.toasts.aiAgentsDisabled);
        refetch();
      },
    }
  );

  const isEditing = !!editingCompany;

  const schema = useMemo(() => createCompanySchema(t), [t]);
  const form = useForm<CreateCompanyFormValues>({
    resolver: zodResolver(schema),
    defaultValues: { name: "", siret: "", first_name: "", last_name: "", email: "", phone: "", password: "" },
  });

  const openCreate = useCallback(() => {
    setEditingCompany(null);
    form.reset({ name: "", siret: "", first_name: "", last_name: "", email: "", phone: "", password: "" });
    setDialogOpen(true);
  }, [form]);

  const lookupMutation = useApiMutation(
    (siret: string) => container.companyRepository.lookup(siret),
    {
      onSuccess: (data) => {
        form.setValue("name", data.name, { shouldValidate: true });
        toast.success(t.companies.toasts.lookupSuccess);
      },
    }
  );

  const handleLookup = useCallback(() => {
    const siret = form.getValues("siret").trim();
    if (siret.length !== 14) {
      toast.error(t.companies.toasts.siretInvalid);
      return;
    }
    lookupMutation.mutate(siret);
  }, [form, lookupMutation]);

  const openEdit = useCallback((company: Company) => {
    setEditingCompany(company);
    form.reset({
      name: company.company_name ?? "",
      siret: company.siret ?? "",
      first_name: company.first_name ?? "",
      last_name: company.last_name ?? "",
      email: company.email ?? "",
      phone: company.phone ?? "",
      password: "",
    });
    setDialogOpen(true);
  }, [form]);

  const onSubmit = async (values: CreateCompanyFormValues) => {
    if (isEditing && editingCompany) {
      const { password, ...rest } = values;
      void password;
      await updateMutation.mutate({ id: editingCompany.id, data: rest });
    } else {
      await createMutation.mutate(values);
    }
  };

  const companies = response?.items ?? [];
  const totalPages = response?.last_page ?? 1;
  const total = response?.total ?? 0;

  return (
    <div className="p-6 space-y-6">
      {stats && (
        <div className="grid grid-cols-2 lg:grid-cols-4 gap-4">
          <StatsCard title={t.companies.stats.total} value={stats.total} icon={Building2} accent="blue" />
          <StatsCard title={t.companies.stats.withVehicles} value={stats.with_vehicles} icon={Car} accent="green" />
          <StatsCard title={t.companies.stats.withSubscription} value={stats.with_subscription} icon={CreditCard} accent="cyan" />
          <StatsCard title={t.companies.stats.new30d} value={stats.new_last_30_days} icon={TrendingUp} accent="purple" />
        </div>
      )}

      {/* Search + Add */}
      <div className="flex items-center gap-3">
        <div className="relative flex-1 max-w-sm">
          <Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground" />
          <Input
            placeholder={t.companies.searchPlaceholder}
            value={pagination.search}
            onChange={(e) => pagination.setSearch(e.target.value)}
            className="pl-9"
          />
        </div>
        <Select
          value={`${pagination.orderBy}:${pagination.order}`}
          onValueChange={(v) => {
            const [field, dir] = v.split(":");
            pagination.setSort(field, dir as "ASC" | "DESC");
          }}
        >
          <SelectTrigger size="sm" className="w-48 gap-2 ml-auto" aria-label={t.companies.sort.label}>
            <ArrowUpDown className="w-3.5 h-3.5 text-muted-foreground" />
            <SelectValue />
          </SelectTrigger>
          <SelectContent>
            <SelectItem value="created_at:DESC">{t.companies.sort.newest}</SelectItem>
            <SelectItem value="created_at:ASC">{t.companies.sort.oldest}</SelectItem>
            <SelectItem value="access_status:DESC">{t.companies.sort.disabledFirst}</SelectItem>
            <SelectItem value="access_status:ASC">{t.companies.sort.enabledFirst}</SelectItem>
          </SelectContent>
        </Select>
        <Button onClick={openCreate} size="sm">
          <Plus className="w-4 h-4 mr-2" />
          {t.common.add}
        </Button>
      </div>

      {/* Company Cards */}
      {/* Skeletons only on first load; keep cards visible during background refetches (e.g. after a status toggle). */}
      {loading && companies.length === 0 ? (
        <div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4">
          {Array.from({ length: 6 }).map((_, i) => (
            <Skeleton key={i} className="h-52 rounded-xl" />
          ))}
        </div>
      ) : companies.length === 0 ? (
        <div className="flex items-center justify-center h-48 rounded-xl border border-dashed border-border">
          <p className="text-sm text-muted-foreground">{t.companies.empty}</p>
        </div>
      ) : (
        <div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4">
          {companies.map((company) => (
            <Card key={company.id} className="group hover:shadow-md transition-all overflow-hidden border-l-4 border-l-blue-500">
              <CardContent className="p-0">
                <div className="px-5 py-4">
                  <div className="flex items-start justify-between gap-3">
                    <div className="flex items-center gap-3 min-w-0 flex-1">
                      <Avatar className="h-11 w-11 flex-shrink-0 ring-2 ring-white dark:ring-background shadow-sm">
                        <AvatarImage src={company.profile_picture ?? undefined} />
                        <AvatarFallback className="bg-blue-500 text-white text-sm font-bold">
                          {(company.company_name ?? "??").slice(0, 2).toUpperCase()}
                        </AvatarFallback>
                      </Avatar>
                      <div className="min-w-0">
                        <p className="text-sm font-semibold text-foreground truncate">
                          {company.company_name ?? t.common.unnamed}
                        </p>
                        <p className="text-xs text-muted-foreground truncate">
                          {company.first_name} {company.last_name}
                        </p>
                      </div>
                    </div>
                    <div className="flex items-start gap-2 flex-shrink-0">
                      <div className="flex flex-wrap items-center justify-end gap-1.5 max-w-[150px]">
                      {company.is_test_account && (
                        <span className="inline-flex items-center gap-1 rounded-full border border-purple-200 bg-purple-100 px-2 py-0.5 text-[10px] font-semibold text-purple-700 dark:border-purple-900 dark:bg-purple-950/40 dark:text-purple-300">
                          <FlaskConical className="w-3 h-3" />
                          {t.companies.testBadge}
                        </span>
                      )}
                      {company.refacturation_feature_granted && (
                        <span className="inline-flex items-center gap-1 rounded-full border border-blue-200 bg-blue-100 px-2 py-0.5 text-[10px] font-semibold text-blue-700 dark:border-blue-900 dark:bg-blue-950/40 dark:text-blue-300">
                          <Receipt className="w-3 h-3" />
                          {t.companies.refacturationBadge}
                        </span>
                      )}
                      {company.ai_agents_enabled && (
                        <span className="inline-flex items-center gap-1 rounded-full border border-violet-200 bg-violet-100 px-2 py-0.5 text-[10px] font-semibold text-violet-700 dark:border-violet-900 dark:bg-violet-950/40 dark:text-violet-300">
                          <Sparkles className="w-3 h-3" />
                          {t.companies.aiAgentsBadge}
                        </span>
                      )}
                      <AccessStatusBadge label={company.access_status.label} color={company.access_status.color} />
                      </div>
                      <DropdownMenu>
                        <DropdownMenuTrigger asChild>
                          <Button variant="ghost" size="icon" className="h-8 w-8 opacity-0 group-hover:opacity-100 transition-opacity">
                            <MoreHorizontal className="w-4 h-4" />
                          </Button>
                        </DropdownMenuTrigger>
                        <DropdownMenuContent align="end">
                          <DropdownMenuItem onClick={() => openEdit(company)}>{t.common.edit}</DropdownMenuItem>
                          {canManagePlans && (
                            <DropdownMenuItem onClick={() => setEntitlementsTarget(company)}>
                              <SlidersHorizontal className="w-4 h-4 mr-2" />
                              {t.entitlements.companyMenu}
                            </DropdownMenuItem>
                          )}
                          {canImpersonate && (
                            <DropdownMenuItem onClick={() => impersonateMutation.mutate(company.id)}>
                              {t.common.impersonate}
                            </DropdownMenuItem>
                          )}
                          {canImpersonate && (
                            <DropdownMenuItem onClick={() => setMcpTokenTarget(company)}>
                              <KeyRound className="w-4 h-4 mr-2" />
                              {t.mcpToken.menuLabel}
                            </DropdownMenuItem>
                          )}
                          <DropdownMenuItem
                            disabled={toggleStatusMutation.loading}
                            onClick={() => toggleStatusMutation.mutate(company.id)}
                          >
                            {company.access_status.enabled ? (
                              <ShieldOff className="w-4 h-4 mr-2" />
                            ) : (
                              <ShieldCheck className="w-4 h-4 mr-2" />
                            )}
                            {company.access_status.enabled ? t.companies.actions.disableAccess : t.companies.actions.enableAccess}
                          </DropdownMenuItem>
                          <DropdownMenuItem
                            disabled={toggleTestMutation.loading}
                            onClick={() => toggleTestMutation.mutate(company.id)}
                          >
                            <FlaskConical className="w-4 h-4 mr-2" />
                            {company.is_test_account ? t.companies.actions.unmarkTest : t.companies.actions.markTest}
                          </DropdownMenuItem>
                          <DropdownMenuItem
                            disabled={toggleRefacturationMutation.loading}
                            onClick={() => toggleRefacturationMutation.mutate(company.id)}
                          >
                            <Receipt className="w-4 h-4 mr-2" />
                            {company.refacturation_feature_granted ? t.companies.actions.revokeRefacturation : t.companies.actions.grantRefacturation}
                          </DropdownMenuItem>
                          <DropdownMenuItem
                            disabled={toggleAiAgentsMutation.loading}
                            onClick={() => toggleAiAgentsMutation.mutate(company.id)}
                          >
                            <Sparkles className="w-4 h-4 mr-2" />
                            {company.ai_agents_enabled ? t.companies.actions.disableAiAgents : t.companies.actions.enableAiAgents}
                          </DropdownMenuItem>
                          <DropdownMenuSeparator />
                          <DropdownMenuItem className="text-destructive" onClick={() => deleteDialog.open(company)}>
                            {t.common.delete}
                          </DropdownMenuItem>
                        </DropdownMenuContent>
                      </DropdownMenu>
                    </div>
                  </div>
                </div>

                {/* Body */}
                <div className="px-5 py-4 space-y-4">
                  <div className="space-y-2 text-xs text-muted-foreground">
                    <div className="flex items-center gap-2">
                      <Mail className="w-3.5 h-3.5 flex-shrink-0 text-blue-500" />
                      <span className="truncate">{company.email}</span>
                    </div>
                    <div className="flex items-center gap-2">
                      <Phone className="w-3.5 h-3.5 flex-shrink-0 text-emerald-500" />
                      <span>{company.phone}</span>
                    </div>
                    <div className="flex items-center gap-2">
                      <Calendar className="w-3.5 h-3.5 flex-shrink-0 text-amber-500" />
                      <span>{formatDate(company.created_at, locale)}</span>
                    </div>
                  </div>

                  <div className="flex items-center gap-2 flex-wrap">
                    <Badge className="gap-1 text-xs bg-cyan-50 text-cyan-700 hover:bg-cyan-100 dark:bg-cyan-950/40 dark:text-cyan-400 border-0">
                      <Car className="w-3 h-3" />
                      {company.vehicles_count}
                    </Badge>
                    <Badge className="gap-1 text-xs bg-amber-50 text-amber-700 hover:bg-amber-100 dark:bg-amber-950/40 dark:text-amber-400 border-0">
                      <MapPin className="w-3 h-3" />
                      {company.sites_count}
                    </Badge>
                    <Badge className="gap-1 text-xs bg-purple-50 text-purple-700 hover:bg-purple-100 dark:bg-purple-950/40 dark:text-purple-400 border-0">
                      <Users className="w-3 h-3" />
                      {company.employees_count}
                    </Badge>
                    {company.subscription_plan && (
                      <Badge className="text-xs bg-emerald-50 text-emerald-700 hover:bg-emerald-100 dark:bg-emerald-950/40 dark:text-emerald-400 border-0">
                        {company.subscription_plan}
                      </Badge>
                    )}
                  </div>
                </div>
              </CardContent>
            </Card>
          ))}
        </div>
      )}

      {/* Pagination */}
      {totalPages > 1 && (
        <div className="flex items-center justify-between text-sm text-muted-foreground">
          <span>{t.companies.countLabel(total)}</span>
          <div className="flex items-center gap-2">
            <Button
              variant="outline"
              size="icon"
              className="h-8 w-8"
              disabled={pagination.page <= 1}
              onClick={() => pagination.setPage(pagination.page - 1)}
            >
              <ChevronLeft className="w-4 h-4" />
            </Button>
            <span className="text-xs font-medium">
              {pagination.page} / {totalPages}
            </span>
            <Button
              variant="outline"
              size="icon"
              className="h-8 w-8"
              disabled={pagination.page >= totalPages}
              onClick={() => pagination.setPage(pagination.page + 1)}
            >
              <ChevronRight className="w-4 h-4" />
            </Button>
          </div>
        </div>
      )}

      {/* Create/Edit Dialog */}
      <Dialog open={dialogOpen} onOpenChange={setDialogOpen}>
        <DialogContent className="max-w-lg">
          <DialogHeader>
            <DialogTitle>{isEditing ? t.companies.dialog.titleEdit : t.companies.dialog.titleCreate}</DialogTitle>
          </DialogHeader>
          <Form {...form}>
            <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">
              <FormField control={form.control} name="name" render={({ field }) => (
                <FormItem>
                  <FormLabel>{t.forms.name}</FormLabel>
                  <FormControl><Input {...field} /></FormControl>
                  <FormMessage />
                </FormItem>
              )} />
              <FormField control={form.control} name="siret" render={({ field }) => (
                <FormItem>
                  <FormLabel>{t.companies.fields.siret}</FormLabel>
                  <div className="flex gap-2">
                    <FormControl><Input placeholder={t.companies.dialog.siretPlaceholder} inputMode="numeric" maxLength={14} {...field} onChange={(e) => field.onChange(e.target.value.replace(/\D/g, "").slice(0, 14))} /></FormControl>
                    <Button
                      type="button"
                      variant="outline"
                      size="icon"
                      className="flex-shrink-0"
                      disabled={lookupMutation.loading}
                      onClick={handleLookup}
                      title={t.companies.dialog.siretLookupTitle}
                    >
                      {lookupMutation.loading ? <Loader2 className="w-4 h-4 animate-spin" /> : <SearchCheck className="w-4 h-4" />}
                    </Button>
                  </div>
                  <FormMessage />
                </FormItem>
              )} />
              <div className="grid grid-cols-2 gap-4">
                <FormField control={form.control} name="first_name" render={({ field }) => (
                  <FormItem>
                    <FormLabel>{t.forms.firstName}</FormLabel>
                    <FormControl><Input {...field} /></FormControl>
                    <FormMessage />
                  </FormItem>
                )} />
                <FormField control={form.control} name="last_name" render={({ field }) => (
                  <FormItem>
                    <FormLabel>{t.forms.lastName}</FormLabel>
                    <FormControl><Input {...field} /></FormControl>
                    <FormMessage />
                  </FormItem>
                )} />
              </div>
              <FormField control={form.control} name="email" render={({ field }) => (
                <FormItem>
                  <FormLabel>{t.forms.email}</FormLabel>
                  <FormControl><Input type="email" {...field} /></FormControl>
                  <FormMessage />
                </FormItem>
              )} />
              <FormField control={form.control} name="phone" render={({ field }) => (
                <FormItem>
                  <FormLabel>{t.forms.phone}</FormLabel>
                  <FormControl><Input {...field} /></FormControl>
                  <FormMessage />
                </FormItem>
              )} />
              {!isEditing && (
                <FormField control={form.control} name="password" render={({ field }) => (
                  <FormItem>
                    <FormLabel>{t.forms.password}</FormLabel>
                    <FormControl><Input type="password" {...field} /></FormControl>
                    <FormMessage />
                  </FormItem>
                )} />
              )}
              <div className="flex justify-end gap-2 pt-2">
                <Button type="button" variant="outline" onClick={() => setDialogOpen(false)}>{t.common.cancel}</Button>
                <Button type="submit" disabled={createMutation.loading || updateMutation.loading}>
                  {(createMutation.loading || updateMutation.loading) && <Loader2 className="w-4 h-4 mr-2 animate-spin" />}
                  {isEditing ? t.common.save : t.common.create}
                </Button>
              </div>
            </form>
          </Form>
        </DialogContent>
      </Dialog>

      {/* Delete Confirmation */}
      <ConfirmationDialog
        open={deleteDialog.isOpen}
        onOpenChange={(open) => !open && deleteDialog.close()}
        title={t.companies.delete.title}
        description={t.companies.delete.description(deleteDialog.target?.company_name ?? undefined)}
        confirmLabel={t.common.delete}
        variant="destructive"
        loading={deleteMutation.loading}
        onConfirm={() => deleteDialog.target && deleteMutation.mutate(deleteDialog.target.id)}
      />

      {/* MCP token — issue a client durable credentials + a ready-to-use Bearer token. */}
      <McpTokenDialog
        open={!!mcpTokenTarget}
        onOpenChange={(open) => !open && setMcpTokenTarget(null)}
        entityLabel={mcpTokenTarget?.company_name ?? ""}
        generate={(payload) => container.companyRepository.generateMcpToken(mcpTokenTarget?.id ?? 0, payload)}
        list={() => container.companyRepository.listMcpTokens(mcpTokenTarget?.id ?? 0)}
        revoke={(credentialId) => container.companyRepository.revokeMcpToken(mcpTokenTarget?.id ?? 0, credentialId)}
      />

      {/* SCRUM-353 — the company's plan and the exceptions that apply to it only. */}
      <CompanyEntitlementsSheet
        companyId={entitlementsTarget?.id ?? null}
        companyName={entitlementsTarget?.company_name ?? ""}
        open={!!entitlementsTarget}
        onOpenChange={(open) => { if (!open) { setEntitlementsTarget(null); refetch(); } }}
      />

    </div>
  );
}
