"use client";

import { useMemo, useState } from "react";
import { useParams, useRouter } from "next/navigation";
import {
  ArrowLeft,
  MapPin,
  User,
  Phone,
  Package,
  Mail,
  Building2,
  CalendarPlus,
  CalendarClock,
  Truck,
  Check,
  X,
  Loader2,
} from "lucide-react";
import { useRepositories } from "@/di/repository-provider";
import { useApiQuery } from "@/presentation/hooks/use-api-query";
import { useApiMutation } from "@/presentation/hooks/use-api-mutation";
import { usePageHeader } from "@/presentation/hooks/use-page-header";
import { useT, useLocale } from "@/shared/i18n/client";
import { formatDate, formatDateTime } from "@/shared/lib/format-date";
import { Button } from "@/presentation/components/ui/button";
import { Badge } from "@/presentation/components/ui/badge";
import { Input } from "@/presentation/components/ui/input";
import { Card, CardContent } from "@/presentation/components/ui/card";
import { Skeleton } from "@/presentation/components/ui/skeleton";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/presentation/components/ui/dialog";
import { StatusPill } from "@/presentation/components/telematics/status-pill";
import RequestInstallationDialog from "@/presentation/components/telematics/request-installation-dialog";
import InstallerAvailabilitiesDialog from "@/presentation/components/telematics/installer-availabilities-dialog";

// L'affectation des véhicules aux installateurs se fait par groupes successifs :
// le bouton reste offert tant que la commande est « livrée » ou « à installer »
// ET qu'il reste des véhicules non affectés (relation many-to-many).
const INSTALLATION_REQUESTABLE_STATUSES = ["delivered", "pending_install"];
// Une fois la demande lancée, l'admin suit les disponibilités des installateurs.
const INSTALLATION_TRACKABLE_STATUSES = ["pending_install", "installed"];
// Statuts pour lesquels on charge les affectations existantes (véhicule → installateur).
const INSTALLATION_ASSIGNMENT_STATUSES = ["delivered", "pending_install", "installed"];
// L'admin peut marquer une commande « En cours » comme « Livré ».
const DELIVERABLE_STATUSES = ["in_progress"];
// Une commande « Lancé » (soumise) est en attente de la décision de l'admin :
// elle peut être acceptée ou refusée.
const DECIDABLE_STATUSES = ["submitted"];

export default function TelematicsOrderDetailPage() {
  const t = useT();
  const locale = useLocale();
  usePageHeader(
    t.pages.telematicsOrderDetail.title,
    t.pages.telematicsOrderDetail.subtitle
  );
  const params = useParams();
  const router = useRouter();
  const container = useRepositories();
  const orderId = Number(params.id);

  const { data: order, loading, refetch } = useApiQuery(
    () => container.telematicsOrderRepository.findById(orderId),
    { deps: [orderId], enabled: !!orderId }
  );

  // Affectations existantes (véhicule → installateur) : source de vérité côté
  // service installateur, relayée par fleet. Sert à griser les véhicules déjà
  // affectés et à afficher leur(s) installateur(s).
  const loadAssignments =
    !!order && INSTALLATION_ASSIGNMENT_STATUSES.includes(order.status);
  const { data: installationRequests, refetch: refetchAssignments } = useApiQuery(
    () => container.telematicsOrderRepository.getInstallationRequests(orderId),
    { deps: [orderId, order?.status], enabled: loadAssignments }
  );

  const { assignedVehicleIds, vehicleInstallers } = useMemo(() => {
    const ids = new Set<number>();
    const installers = new Map<number, string[]>();
    for (const req of installationRequests ?? []) {
      if (req.status === "cancelled") continue;
      for (const v of req.vehicles ?? []) {
        if (v.id == null) continue;
        ids.add(v.id);
        if (req.installer_name) {
          const list = installers.get(v.id) ?? [];
          if (!list.includes(req.installer_name)) list.push(req.installer_name);
          installers.set(v.id, list);
        }
      }
    }
    return { assignedVehicleIds: ids, vehicleInstallers: installers };
  }, [installationRequests]);

  const unassignedVehicleCount =
    (order?.vehicles ?? []).filter((v) => !assignedVehicleIds.has(v.id)).length;

  const refetchAll = () => {
    refetch();
    refetchAssignments();
  };

  const [requestOpen, setRequestOpen] = useState(false);
  const [availabilitiesOpen, setAvailabilitiesOpen] = useState(false);
  const today = new Date().toISOString().slice(0, 10);
  const [acceptOpen, setAcceptOpen] = useState(false);
  const [acceptDate, setAcceptDate] = useState(today);
  const [acceptNote, setAcceptNote] = useState("");
  const [rejectOpen, setRejectOpen] = useState(false);
  const [rejectReason, setRejectReason] = useState("");
  const [deliverOpen, setDeliverOpen] = useState(false);
  const [deliverDate, setDeliverDate] = useState(today);

  const markDelivered = useApiMutation(
    (receivedDate: string) =>
      container.telematicsOrderRepository.markDelivered(orderId, receivedDate),
    {
      successMessage: t.telematics.markDelivered.success,
      onSuccess: () => {
        setDeliverOpen(false);
        setDeliverDate(today);
        refetch();
        // SCRUM-271: une commande livrée déclenche d'elle-même la proposition
        // de lancer la demande d'installation (popup « Commande livrée »),
        // sans attendre un clic sur « Demander l'installation ».
        setRequestOpen(true);
      },
    }
  );

  const acceptMutation = useApiMutation(
    ({ orderDate, note }: { orderDate: string; note?: string }) =>
      container.telematicsOrderRepository.accept(orderId, orderDate, note),
    {
      successMessage: t.telematics.orders.toasts.accepted,
      onSuccess: () => {
        setAcceptOpen(false);
        setAcceptDate(today);
        setAcceptNote("");
        refetch();
      },
    }
  );

  const rejectMutation = useApiMutation(
    (reason: string) => container.telematicsOrderRepository.reject(orderId, reason),
    {
      successMessage: t.telematics.orders.toasts.rejected,
      onSuccess: () => {
        setRejectOpen(false);
        setRejectReason("");
        refetch();
      },
    }
  );

  const formatMoney = (value: number) =>
    new Intl.NumberFormat(locale === "fr" ? "fr-FR" : "en-US", {
      style: "currency",
      currency: "EUR",
      maximumFractionDigits: 0,
    }).format(value);

  if (loading) {
    return (
      <div className="p-6 space-y-6">
        <Skeleton className="h-12 w-72" />
        <div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
          <div className="lg:col-span-2 space-y-4">
            <Skeleton className="h-32 rounded-xl" />
            <Skeleton className="h-48 rounded-xl" />
          </div>
          <Skeleton className="h-96 rounded-xl" />
        </div>
      </div>
    );
  }

  if (!order) {
    return (
      <div className="p-6">
        <div className="flex items-center justify-center h-48 rounded-xl border border-dashed border-border">
          <p className="text-sm text-muted-foreground">
            {t.telematics.orderDetail.notFound}
          </p>
        </div>
      </div>
    );
  }

  const { lines, shipments, needs, pricing, summary } = order;

  return (
    <div className="p-6 space-y-6">
      {/* Header */}
      <div className="flex items-start justify-between gap-3">
        <div className="flex items-start gap-3 min-w-0">
          <Button
            variant="ghost"
            size="icon"
            onClick={() => router.push("/commandes-telematique")}
          >
            <ArrowLeft className="w-4 h-4" />
          </Button>
          <div className="min-w-0">
            <div className="flex items-center gap-3">
              <h2 className="text-xl font-bold text-foreground">{order.reference}</h2>
              <StatusPill label={order.status_label} color={order.status_color} />
            </div>
            <p className="text-sm text-muted-foreground mt-0.5">
              {t.telematics.orderDetail.subtitle(
                order.organization.name,
                formatDateTime(order.submitted_at, locale)
              )}
            </p>
          </div>
        </div>
        {DECIDABLE_STATUSES.includes(order.status) && (
          <div className="flex shrink-0 items-center gap-2">
            <Button
              variant="outline"
              className="border-destructive/40 text-destructive hover:bg-destructive/10 hover:text-destructive"
              onClick={() => setRejectOpen(true)}
            >
              <X className="w-4 h-4 mr-2" />
              {t.telematics.orders.actions.reject}
            </Button>
            <Button
              className="bg-emerald-600 text-white hover:bg-emerald-700"
              onClick={() => {
                setAcceptDate(today);
                setAcceptNote("");
                setAcceptOpen(true);
              }}
            >
              <Check className="w-4 h-4 mr-2" />
              {t.telematics.orders.actions.accept}
            </Button>
          </div>
        )}
        {DELIVERABLE_STATUSES.includes(order.status) && (
          <Button
            className="shrink-0"
            onClick={() => {
              setDeliverDate(today);
              setDeliverOpen(true);
            }}
          >
            <Truck className="w-4 h-4 mr-2" />
            {t.telematics.markDelivered.action}
          </Button>
        )}
        {INSTALLATION_REQUESTABLE_STATUSES.includes(order.status) &&
          unassignedVehicleCount > 0 && (
            <Button className="shrink-0" onClick={() => setRequestOpen(true)}>
              <CalendarPlus className="w-4 h-4 mr-2" />
              {t.telematics.requestInstallation.action}
            </Button>
          )}
        {INSTALLATION_TRACKABLE_STATUSES.includes(order.status) && (
          <Button
            variant="outline"
            className="shrink-0"
            onClick={() => setAvailabilitiesOpen(true)}
          >
            <CalendarClock className="w-4 h-4 mr-2" />
            {t.telematics.installerAvailabilities.action}
          </Button>
        )}
      </div>

      <div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
        {/* Main */}
        <div className="lg:col-span-2 space-y-4">
          {/* Lines */}
          {lines.map((line) => (
            <Card key={line.id}>
              <CardContent className="p-5">
                <div className="flex items-start justify-between gap-4">
                  <div className="flex items-start gap-3 min-w-0">
                    <div className="w-11 h-11 rounded-lg bg-muted flex items-center justify-center shrink-0">
                      <Package className="w-5 h-5 text-muted-foreground" />
                    </div>
                    <div className="min-w-0">
                      <p className="font-semibold text-base">{line.product_name}</p>
                      {line.product_tagline && (
                        <p className="text-xs text-muted-foreground">
                          {line.product_tagline}
                        </p>
                      )}
                    </div>
                  </div>
                  <div className="text-right shrink-0">
                    <p className="text-xs text-muted-foreground">
                      {t.telematics.orderDetail.fields.unitPrice(
                        line.quantity,
                        formatMoney(line.unit_price)
                      )}
                    </p>
                    <p className="text-base font-semibold">
                      {formatMoney(line.line_total)}
                    </p>
                  </div>
                </div>
              </CardContent>
            </Card>
          ))}

          {/* Shipments */}
          {shipments.length > 0 && (
            <Card>
              <CardContent className="p-5 space-y-4">
                <h3 className="text-base font-semibold">
                  {t.telematics.orderDetail.sections.delivery(summary.sites)}
                </h3>
                <div className="space-y-3">
                  {shipments.map((s, idx) => (
                    <div
                      key={`${s.site_name}-${idx}`}
                      className="rounded-lg border border-border p-4"
                    >
                      <div className="flex items-start justify-between gap-2">
                        <p className="font-medium">{s.site_name}</p>
                        <Badge variant="secondary" className="text-xs shrink-0">
                          {t.telematics.orderDetail.fields.units(s.units)}
                        </Badge>
                      </div>
                      <div className="mt-2 space-y-1.5 text-sm text-muted-foreground">
                        {s.address && (
                          <p className="flex items-center gap-2">
                            <MapPin className="w-3.5 h-3.5" />
                            {s.address}
                          </p>
                        )}
                        {s.contact_name && (
                          <p className="flex items-center gap-2">
                            <User className="w-3.5 h-3.5" />
                            {s.contact_name}
                          </p>
                        )}
                        {s.contact_phone && (
                          <p className="flex items-center gap-2">
                            <Phone className="w-3.5 h-3.5" />
                            {s.contact_phone}
                          </p>
                        )}
                        {s.contact_email && (
                          <p className="flex items-center gap-2">
                            <Mail className="w-3.5 h-3.5" />
                            {s.contact_email}
                          </p>
                        )}
                      </div>
                    </div>
                  ))}
                </div>
              </CardContent>
            </Card>
          )}

          {/* Needs */}
          <Card>
            <CardContent className="p-5 space-y-3">
              <h3 className="text-base font-semibold">
                {t.telematics.orderDetail.sections.needs}
              </h3>
              {needs.length > 0 ? (
                <div className="flex flex-wrap gap-2">
                  {needs.map((n) => (
                    <Badge key={n} variant="secondary" className="text-xs">
                      {n}
                    </Badge>
                  ))}
                </div>
              ) : (
                <p className="text-sm text-muted-foreground">
                  {t.telematics.orderDetail.fields.noNeeds}
                </p>
              )}
            </CardContent>
          </Card>
        </div>

        {/* Sidebar */}
        <div className="space-y-4">
          <Card>
            <CardContent className="p-5">
              <p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
                {t.telematics.orderDetail.sections.totalCommande}
              </p>
              <p className="text-4xl font-bold mt-2">
                {formatMoney(pricing.total_ttc)}
              </p>
              <p className="text-xs text-muted-foreground mt-1">
                {t.telematics.orderDetail.sections.ttc}
              </p>
            </CardContent>
          </Card>

          <Card>
            <CardContent className="p-5 space-y-3">
              <h3 className="text-base font-semibold">
                {t.telematics.orderDetail.sections.summary}
              </h3>
              <div className="space-y-2 text-sm">
                <Row
                  label={t.telematics.orderDetail.fields.lines}
                  value={summary.lines}
                />
                <Row
                  label={t.telematics.orderDetail.fields.boxes}
                  value={summary.boxes}
                />
                <Row
                  label={t.telematics.orderDetail.fields.sites}
                  value={summary.sites}
                />
                <Row
                  label={t.telematics.orderDetail.fields.installation}
                  value={pricing.installation_mode}
                />
                <div className="border-t border-border my-2" />
                <Row
                  label={t.telematics.orderDetail.fields.totalHt}
                  value={formatMoney(pricing.total_ht)}
                />
                <Row
                  label={t.telematics.orderDetail.fields.vat(pricing.vat_rate)}
                  value={formatMoney(pricing.vat_amount)}
                />
                <Row
                  label={t.telematics.orderDetail.fields.totalTtc}
                  value={formatMoney(pricing.total_ttc)}
                  strong
                />
              </div>
            </CardContent>
          </Card>

          <Card>
            <CardContent className="p-5 space-y-3">
              <h3 className="text-base font-semibold">
                {t.telematics.orderDetail.sections.dates}
              </h3>
              <div className="space-y-3 text-sm">
                <div className="flex items-center gap-3">
                  <div className="w-9 h-9 rounded-lg bg-muted flex items-center justify-center shrink-0">
                    <CalendarPlus className="w-4 h-4 text-muted-foreground" />
                  </div>
                  <div className="min-w-0">
                    <p className="text-xs text-muted-foreground">
                      {t.telematics.orderDetail.fields.orderDate}
                    </p>
                    <p className="font-medium">
                      {order.order_date
                        ? formatDate(order.order_date, locale)
                        : t.telematics.orderDetail.fields.dateNotSet}
                    </p>
                  </div>
                </div>
                <div className="flex items-center gap-3">
                  <div className="w-9 h-9 rounded-lg bg-muted flex items-center justify-center shrink-0">
                    <Truck className="w-4 h-4 text-muted-foreground" />
                  </div>
                  <div className="min-w-0">
                    <p className="text-xs text-muted-foreground">
                      {t.telematics.orderDetail.fields.receivedDate}
                    </p>
                    <p className="font-medium">
                      {order.received_at
                        ? formatDate(order.received_at, locale)
                        : t.telematics.orderDetail.fields.dateNotSet}
                    </p>
                  </div>
                </div>
              </div>
            </CardContent>
          </Card>

          {order.demandeur && (
            <Card>
              <CardContent className="p-5 space-y-2">
                <h3 className="text-base font-semibold">
                  {t.telematics.orderDetail.sections.demandeur}
                </h3>
                <p className="font-medium text-sm">{order.demandeur.name}</p>
                {order.demandeur.email && (
                  <p className="flex items-center gap-2 text-sm text-muted-foreground">
                    <Mail className="w-3.5 h-3.5" />
                    {order.demandeur.email}
                  </p>
                )}
                {order.demandeur.organization && (
                  <p className="flex items-center gap-2 text-sm text-muted-foreground">
                    <Building2 className="w-3.5 h-3.5" />
                    {order.demandeur.organization}
                  </p>
                )}
              </CardContent>
            </Card>
          )}
        </div>
      </div>

      {/* Accept */}
      <Dialog
        open={acceptOpen}
        onOpenChange={(open) => {
          setAcceptOpen(open);
          if (!open) {
            setAcceptDate(today);
            setAcceptNote("");
          }
        }}
      >
        <DialogContent onOpenAutoFocus={(e) => e.preventDefault()}>
          <DialogHeader>
            <DialogTitle>{t.telematics.orders.lifecycle.acceptTitle}</DialogTitle>
            <DialogDescription>
              {t.telematics.orders.lifecycle.acceptDescription}
            </DialogDescription>
          </DialogHeader>
          <div className="space-y-1.5">
            <label className="text-sm font-medium">
              {t.telematics.orders.lifecycle.acceptOrderDateLabel}
            </label>
            <Input
              type="date"
              value={acceptDate}
              onChange={(e) => setAcceptDate(e.target.value)}
            />
          </div>
          <textarea
            className="flex min-h-[100px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-xs placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
            value={acceptNote}
            placeholder={t.telematics.orders.lifecycle.acceptNotePlaceholder}
            onChange={(e) => setAcceptNote(e.target.value)}
          />
          <DialogFooter>
            <Button variant="outline" onClick={() => setAcceptOpen(false)}>
              {t.common.cancel}
            </Button>
            <Button
              className="bg-emerald-600 text-white hover:bg-emerald-700"
              disabled={!acceptDate || acceptMutation.loading}
              onClick={() =>
                acceptMutation.mutate({
                  orderDate: acceptDate,
                  note: acceptNote.trim() || undefined,
                })
              }
            >
              {acceptMutation.loading && (
                <Loader2 className="w-4 h-4 mr-2 animate-spin" />
              )}
              {t.telematics.orders.lifecycle.confirm}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* Reject */}
      <Dialog
        open={rejectOpen}
        onOpenChange={(open) => {
          setRejectOpen(open);
          if (!open) setRejectReason("");
        }}
      >
        <DialogContent onOpenAutoFocus={(e) => e.preventDefault()}>
          <DialogHeader>
            <DialogTitle>{t.telematics.orders.lifecycle.rejectTitle}</DialogTitle>
            <DialogDescription>
              {t.telematics.orders.lifecycle.rejectDescription}
            </DialogDescription>
          </DialogHeader>
          <textarea
            className="flex min-h-[100px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-xs placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
            value={rejectReason}
            placeholder={t.telematics.orders.lifecycle.rejectReasonPlaceholder}
            onChange={(e) => setRejectReason(e.target.value)}
          />
          <DialogFooter>
            <Button variant="outline" onClick={() => setRejectOpen(false)}>
              {t.common.cancel}
            </Button>
            <Button
              className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
              disabled={!rejectReason.trim() || rejectMutation.loading}
              onClick={() => rejectMutation.mutate(rejectReason.trim())}
            >
              {rejectMutation.loading && (
                <Loader2 className="w-4 h-4 mr-2 animate-spin" />
              )}
              {t.telematics.orders.lifecycle.confirm}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* Mark delivered */}
      <Dialog
        open={deliverOpen}
        onOpenChange={(open) => {
          setDeliverOpen(open);
          if (!open) setDeliverDate(today);
        }}
      >
        <DialogContent onOpenAutoFocus={(e) => e.preventDefault()}>
          <DialogHeader>
            <DialogTitle>{t.telematics.markDelivered.title}</DialogTitle>
            <DialogDescription>
              {t.telematics.markDelivered.description}
            </DialogDescription>
          </DialogHeader>
          <div className="space-y-1.5">
            <label className="text-sm font-medium">
              {t.telematics.markDelivered.receivedDateLabel}
            </label>
            <Input
              type="date"
              value={deliverDate}
              onChange={(e) => setDeliverDate(e.target.value)}
            />
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={() => setDeliverOpen(false)}>
              {t.common.cancel}
            </Button>
            <Button
              disabled={!deliverDate || markDelivered.loading}
              onClick={() => markDelivered.mutate(deliverDate)}
            >
              {markDelivered.loading && (
                <Loader2 className="w-4 h-4 mr-2 animate-spin" />
              )}
              {t.telematics.markDelivered.confirm}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      <RequestInstallationDialog
        order={order}
        open={requestOpen}
        onOpenChange={setRequestOpen}
        onSuccess={refetchAll}
        assignedVehicleIds={assignedVehicleIds}
        vehicleInstallers={vehicleInstallers}
      />

      <InstallerAvailabilitiesDialog
        orderId={order.id}
        reference={order.reference}
        open={availabilitiesOpen}
        onOpenChange={setAvailabilitiesOpen}
      />
    </div>
  );
}

function Row({
  label,
  value,
  strong,
}: {
  label: string;
  value: React.ReactNode;
  strong?: boolean;
}) {
  return (
    <div
      className={`flex items-center justify-between ${
        strong ? "font-semibold text-foreground" : ""
      }`}
    >
      <span className="text-muted-foreground">{label}</span>
      <span>{value}</span>
    </div>
  );
}
