"use client";

import { useCallback, useEffect, useMemo, useState } from "react";
import { useParams } from "next/navigation";
import { Pencil, RefreshCw } from "lucide-react";
import { PageHeader } from "@/components/layout/PageHeader";
import { ErrorState } from "@/components/layout/ErrorState";
import { Badge } from "@/components/ui/badge";
import { StatusBadge } from "@/components/ui/status-badge";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Skeleton } from "@/components/ui/skeleton";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import { apiFetch, errorMessageForUi } from "@/lib/api";
import {
  addinAccessLabel,
  formatEntitledProducts,
  type EntitlementSummary,
} from "@/lib/entitlements";
import {
  connectionBadgeVariant,
  connectionStatusIndicator,
  formatConnectionStatus,
  formatDateTime,
} from "@/lib/geotab-display";
import {
  assertSafeGeotabResponse,
  buildGeotabConfigurePayload,
  credentialsLabel,
  initialIntegrationMode,
  subscriptionLabel,
  validateGeotabConfigForm,
  type GeotabConfigFormValues,
} from "@/lib/onboarding";
import {
  formatSubscriptionSource,
  formatSubscriptionStatus,
  formatTenantStatus,
  subscriptionSourceBadgeVariant,
  subscriptionStatusBadgeVariant,
  tenantStatusBadgeVariant,
  tenantStatusIndicator,
} from "@/lib/status";

type GeotabAccount = {
  id: string;
  databaseName: string;
  server?: string | null;
  username?: string | null;
  connectionStatus: string;
  isConnected: boolean;
  hasCredentials?: boolean;
  addinStatus?: string | null;
  lastCheckedAt?: string | null;
  lastSyncAt?: string | null;
  lastError?: string | null;
  vehicleCount?: number;
};

type TenantDetail = {
  id: string;
  name: string;
  slug: string;
  status: string;
  companyName?: string | null;
  billingEmail?: string | null;
  primaryAdmin?: { id: string; email: string; role: string; isActive: boolean } | null;
  users: Array<{ id: string; email: string; role: string; isActive: boolean }>;
  vehicles: Array<{
    id: string;
    name: string;
    geotabDeviceId?: string | null;
    isActive: boolean;
    lastSyncedAt?: string | null;
  }>;
  subscriptions: Array<{
    id: string;
    status: string;
    source?: string;
    stripeSubscriptionId?: string | null;
    plan: { name: string; code: string };
  }>;
  geotabAccounts: GeotabAccount[];
  _count?: { users: number; vehicles: number };
};

type AuditLog = {
  id: string;
  action: string;
  summary?: string | null;
  createdAt: string;
  user?: { email: string } | null;
};

type ActionResult = {
  message: string;
  connectionStatus?: string;
  created?: number;
  updated?: number;
  deactivated?: number;
  synced?: number;
  lastSyncAt?: string | null;
};

const emptyConfig = (geotab?: GeotabAccount | null): GeotabConfigFormValues => ({
  databaseName: geotab?.databaseName || "",
  server: geotab?.server || "my.geotab.com",
  username: geotab?.username || "",
  password: "",
});

export default function CustomerDetailPage() {
  const params = useParams<{ id: string }>();
  const [tenant, setTenant] = useState<TenantDetail | null>(null);
  const [entitlements, setEntitlements] = useState<EntitlementSummary | null>(null);
  const [logs, setLogs] = useState<AuditLog[]>([]);
  const [error, setError] = useState<string | null>(null);
  const [loading, setLoading] = useState(true);
  const [busy, setBusy] = useState<"check" | "sync" | "save" | null>(null);
  const [actionMessage, setActionMessage] = useState<string | null>(null);
  const [actionError, setActionError] = useState<string | null>(null);
  const [editing, setEditing] = useState(false);
  const [form, setForm] = useState<GeotabConfigFormValues>(emptyConfig());
  const [formError, setFormError] = useState<string | null>(null);

  const load = useCallback(async () => {
    if (!params.id) return;
    const [t, a, e] = await Promise.all([
      apiFetch<TenantDetail>(`/tenants/${params.id}`),
      apiFetch<AuditLog[]>(`/audit?tenantId=${params.id}`).catch(() => [] as AuditLog[]),
      apiFetch<EntitlementSummary>(`/entitlements?tenantId=${params.id}`).catch(
        () => null,
      ),
    ]);
    setTenant(t);
    setLogs(a);
    setEntitlements(e);
    const geotab = t.geotabAccounts[0];
    setForm((prev) => ({
      ...emptyConfig(geotab),
      // Keep password empty always after refresh — write-only
      password: "",
      // Preserve in-progress edits only while editing; otherwise refresh fields
      ...(editing
        ? {
            databaseName: prev.databaseName || geotab?.databaseName || "",
            server: prev.server || geotab?.server || "my.geotab.com",
            username: prev.username || geotab?.username || "",
            password: "",
          }
        : {}),
    }));
  }, [params.id, editing]);

  useEffect(() => {
    setLoading(true);
    load()
      .catch((err) => setError(errorMessageForUi(err, "Failed")))
      .finally(() => setLoading(false));
  }, [load]);

  const geotab = tenant?.geotabAccounts[0];
  const admin =
    tenant?.primaryAdmin ||
    tenant?.users.find((u) => u.role === "CUSTOMER_ADMIN") ||
    null;
  const vehicleCount = tenant?._count?.vehicles ?? tenant?.vehicles.length ?? 0;
  const subscription = tenant?.subscriptions[0];

  const mode = useMemo(
    () =>
      initialIntegrationMode({
        hasAccount: Boolean(geotab),
        hasCredentials: Boolean(geotab?.hasCredentials),
        editing,
      }),
    [geotab, editing],
  );

  async function runCheck(accountId: string) {
    setBusy("check");
    setActionError(null);
    setActionMessage(null);
    try {
      const result = await apiFetch<ActionResult>(
        `/geotab/accounts/${accountId}/check-connection`,
        { method: "POST" },
      );
      setActionMessage(result.message);
      await load();
    } catch (err) {
      const message = errorMessageForUi(err, "Check failed");
      if (message) setActionError(message);
    } finally {
      setBusy(null);
    }
  }

  async function runSync(accountId: string) {
    setBusy("sync");
    setActionError(null);
    setActionMessage(null);
    try {
      const result = await apiFetch<ActionResult>(
        `/geotab/accounts/${accountId}/sync-vehicles`,
        { method: "POST" },
      );
      const synced =
        typeof result.synced === "number"
          ? result.synced
          : (result.created ?? 0) + (result.updated ?? 0);
      setActionMessage(`${result.message} · ${synced} vehicle(s) synchronized`);
      await load();
    } catch (err) {
      const message = errorMessageForUi(err, "Sync failed");
      if (message) setActionError(message);
    } finally {
      setBusy(null);
    }
  }

  async function saveConfig() {
    if (!tenant) return;
    const validation = validateGeotabConfigForm(form);
    if (validation) {
      setFormError(validation);
      return;
    }
    setBusy("save");
    setFormError(null);
    setActionError(null);
    setActionMessage(null);
    try {
      const payload = buildGeotabConfigurePayload(tenant.id, form);
      const saved = await apiFetch<GeotabAccount>("/geotab/accounts", {
        method: "PUT",
        body: JSON.stringify(payload),
      });
      if (!assertSafeGeotabResponse(saved)) {
        throw new Error("Unsafe integration response rejected by client");
      }
      // Clear write-only password from memory immediately
      setForm((prev) => ({ ...prev, password: "" }));
      setEditing(false);
      setActionMessage("MyGeotab configuration saved. Credentials configured.");
      await load();
    } catch (err) {
      const message = errorMessageForUi(err, "Save failed");
      if (message) setFormError(message);
    } finally {
      setBusy(null);
    }
  }

  if (loading) return <Skeleton className="h-64 w-full" />;
  if (error) return <ErrorState message={error} />;
  if (!tenant) return null;

  return (
    <>
      <PageHeader
        title={tenant.name}
        description={`${tenant.slug} · onboarding`}
        actions={
          <StatusBadge
            variant={tenantStatusBadgeVariant(tenant.status)}
            indicator={tenantStatusIndicator(tenant.status)}
          >
            {formatTenantStatus(tenant.status)}
          </StatusBadge>
        }
      />

      <div className="mb-6 grid gap-3 sm:grid-cols-2 xl:grid-cols-4">
        <Card>
          <CardHeader className="pb-2">
            <CardDescription>Customer</CardDescription>
            <CardTitle className="text-xl">{tenant.name}</CardTitle>
          </CardHeader>
          <CardContent className="text-xs text-muted-foreground">
            Admin: {admin?.email || "—"}
          </CardContent>
        </Card>
        <Card>
          <CardHeader className="pb-2">
            <CardDescription>Status</CardDescription>
            <CardTitle className="text-xl">
              <StatusBadge
                variant={tenantStatusBadgeVariant(tenant.status)}
                indicator={tenantStatusIndicator(tenant.status)}
              >
                {formatTenantStatus(tenant.status)}
              </StatusBadge>
            </CardTitle>
          </CardHeader>
        </Card>
        <Card>
          <CardHeader className="pb-2">
            <CardDescription>MyGeotab</CardDescription>
            <CardTitle className="text-xl">
              <StatusBadge
                variant={connectionBadgeVariant(geotab?.connectionStatus ?? "NOT_CONFIGURED")}
                indicator={connectionStatusIndicator(geotab?.connectionStatus ?? "NOT_CONFIGURED")}
              >
                {formatConnectionStatus(geotab?.connectionStatus ?? "NOT_CONFIGURED")}
              </StatusBadge>
            </CardTitle>
          </CardHeader>
        </Card>
        <Card>
          <CardHeader className="pb-2">
            <CardDescription>Vehicles</CardDescription>
            <CardTitle className="text-3xl">{vehicleCount}</CardTitle>
          </CardHeader>
          <CardContent className="text-xs text-muted-foreground">
            Subscription: {subscriptionLabel(subscription)}
          </CardContent>
        </Card>
      </div>

      <Tabs defaultValue="integration" className="space-y-4">
        <TabsList className="flex h-auto flex-wrap">
          <TabsTrigger value="overview">Overview</TabsTrigger>
          <TabsTrigger value="integration">Integration</TabsTrigger>
          <TabsTrigger value="vehicles">Vehicles</TabsTrigger>
          <TabsTrigger value="subscription">Subscription</TabsTrigger>
          <TabsTrigger value="audit">Audit</TabsTrigger>
        </TabsList>

        <TabsContent value="overview">
          <Card>
            <CardHeader>
              <CardTitle>Account</CardTitle>
              <CardDescription>
                Customer-user management UI is intentionally omitted for MVP.
              </CardDescription>
            </CardHeader>
            <CardContent className="grid gap-3 text-sm sm:grid-cols-2">
              <div>
                <p className="text-muted-foreground">Company</p>
                <p className="font-medium">{tenant.companyName || "—"}</p>
              </div>
              <div>
                <p className="text-muted-foreground">Billing email</p>
                <p className="font-medium">{tenant.billingEmail || "—"}</p>
              </div>
              <div>
                <p className="text-muted-foreground">Primary admin</p>
                <p className="font-medium">{admin?.email || "—"}</p>
              </div>
              <div>
                <p className="text-muted-foreground">Subscription</p>
                <p className="font-medium">{subscriptionLabel(subscription)}</p>
              </div>
            </CardContent>
          </Card>
        </TabsContent>

        <TabsContent value="integration" className="space-y-4">
          {actionError ? (
            <Alert variant="destructive">
              <AlertTitle>Action failed</AlertTitle>
              <AlertDescription>{actionError}</AlertDescription>
            </Alert>
          ) : null}
          {actionMessage ? (
            <Alert>
              <AlertTitle>Success</AlertTitle>
              <AlertDescription>{actionMessage}</AlertDescription>
            </Alert>
          ) : null}

          {mode === "status" && geotab ? (
            <Card>
              <CardHeader>
                <div className="flex flex-wrap items-start justify-between gap-3">
                  <div>
                    <CardTitle>MyGeotab Integration</CardTitle>
                    <CardDescription>Credentials are never displayed after save.</CardDescription>
                  </div>
                  <div className="flex flex-wrap gap-2">
                    <Button
                      size="sm"
                      variant="outline"
                      disabled={busy !== null}
                      onClick={() => void runCheck(geotab.id)}
                    >
                      <RefreshCw
                        className={`mr-2 h-4 w-4 ${busy === "check" ? "animate-spin" : ""}`}
                      />
                      Test Connection
                    </Button>
                    <Button
                      size="sm"
                      disabled={busy !== null}
                      onClick={() => void runSync(geotab.id)}
                    >
                      <RefreshCw
                        className={`mr-2 h-4 w-4 ${busy === "sync" ? "animate-spin" : ""}`}
                      />
                      Sync Vehicles
                    </Button>
                    <Button
                      size="sm"
                      variant="secondary"
                      disabled={busy !== null}
                      onClick={() => {
                        setEditing(true);
                        setForm(emptyConfig(geotab));
                        setFormError(null);
                      }}
                    >
                      <Pencil className="mr-2 h-4 w-4" />
                      Edit Configuration
                    </Button>
                  </div>
                </div>
              </CardHeader>
              <CardContent className="grid gap-3 text-sm sm:grid-cols-2">
                <div>
                  <p className="text-muted-foreground">Status</p>
                  <div className="mt-1">
                    <StatusBadge
                      variant={connectionBadgeVariant(geotab.connectionStatus)}
                      indicator={connectionStatusIndicator(geotab.connectionStatus)}
                    >
                      {formatConnectionStatus(geotab.connectionStatus)}
                    </StatusBadge>
                  </div>
                </div>
                <div>
                  <p className="text-muted-foreground">Credentials</p>
                  <p className="font-medium">{credentialsLabel(geotab.hasCredentials)}</p>
                </div>
                <div>
                  <p className="text-muted-foreground">Database</p>
                  <p className="font-medium">{geotab.databaseName}</p>
                </div>
                <div>
                  <p className="text-muted-foreground">Server</p>
                  <p className="font-medium">{geotab.server || "—"}</p>
                </div>
                <div>
                  <p className="text-muted-foreground">Username</p>
                  <p className="font-medium">{geotab.username || "—"}</p>
                </div>
                <div>
                  <p className="text-muted-foreground">Vehicles</p>
                  <p className="font-medium">{geotab.vehicleCount ?? vehicleCount}</p>
                </div>
                <div>
                  <p className="text-muted-foreground">Last Connection Check</p>
                  <p className="font-medium">{formatDateTime(geotab.lastCheckedAt)}</p>
                </div>
                <div>
                  <p className="text-muted-foreground">Last Vehicle Sync</p>
                  <p className="font-medium">{formatDateTime(geotab.lastSyncAt)}</p>
                </div>
                {geotab.lastError && geotab.connectionStatus === "ERROR" ? (
                  <div className="sm:col-span-2">
                    <Alert variant="destructive">
                      <AlertTitle>Last error</AlertTitle>
                      <AlertDescription>{geotab.lastError}</AlertDescription>
                    </Alert>
                  </div>
                ) : null}
              </CardContent>
            </Card>
          ) : (
            <Card>
              <CardHeader>
                <CardTitle>Configure MyGeotab</CardTitle>
                <CardDescription>
                  Password is write-only. After saving you will only see “Credentials configured”.
                </CardDescription>
              </CardHeader>
              <CardContent className="space-y-4">
                <div className="grid gap-3 sm:grid-cols-2">
                  <div className="grid gap-1.5 sm:col-span-2">
                    <Label htmlFor="gt-db">Database Name</Label>
                    <Input
                      id="gt-db"
                      value={form.databaseName}
                      onChange={(e) =>
                        setForm((prev) => ({ ...prev, databaseName: e.target.value }))
                      }
                      autoComplete="off"
                    />
                  </div>
                  <div className="grid gap-1.5">
                    <Label htmlFor="gt-server">Server</Label>
                    <Input
                      id="gt-server"
                      value={form.server}
                      onChange={(e) => setForm((prev) => ({ ...prev, server: e.target.value }))}
                      placeholder="my.geotab.com"
                      autoComplete="off"
                    />
                  </div>
                  <div className="grid gap-1.5">
                    <Label htmlFor="gt-user">Username</Label>
                    <Input
                      id="gt-user"
                      value={form.username}
                      onChange={(e) => setForm((prev) => ({ ...prev, username: e.target.value }))}
                      autoComplete="off"
                    />
                  </div>
                  <div className="grid gap-1.5 sm:col-span-2">
                    <Label htmlFor="gt-pass">Password</Label>
                    <Input
                      id="gt-pass"
                      type="password"
                      value={form.password}
                      onChange={(e) => setForm((prev) => ({ ...prev, password: e.target.value }))}
                      autoComplete="new-password"
                      placeholder={
                        geotab?.hasCredentials
                          ? "Enter a new password to replace existing credentials"
                          : "Enter MyGeotab password"
                      }
                    />
                    {geotab?.hasCredentials ? (
                      <p className="text-xs text-muted-foreground">
                        Current credentials: Configured (password never shown)
                      </p>
                    ) : null}
                  </div>
                </div>

                {formError ? (
                  <Alert variant="destructive">
                    <AlertTitle>Could not save</AlertTitle>
                    <AlertDescription>{formError}</AlertDescription>
                  </Alert>
                ) : null}

                <div className="flex flex-wrap gap-2">
                  <Button disabled={busy !== null} onClick={() => void saveConfig()}>
                    {busy === "save" ? "Saving…" : "Save configuration"}
                  </Button>
                  {editing && geotab?.hasCredentials ? (
                    <Button
                      variant="outline"
                      disabled={busy !== null}
                      onClick={() => {
                        setEditing(false);
                        setForm(emptyConfig(geotab));
                        setFormError(null);
                      }}
                    >
                      Cancel
                    </Button>
                  ) : null}
                </div>
              </CardContent>
            </Card>
          )}
        </TabsContent>

        <TabsContent value="vehicles">
          <div className="overflow-hidden rounded-lg border bg-card">
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead>Vehicle</TableHead>
                  <TableHead className="hidden sm:table-cell">Device ID</TableHead>
                  <TableHead>Status</TableHead>
                  <TableHead className="hidden md:table-cell">Last Synced</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {tenant.vehicles.map((v) => (
                  <TableRow key={v.id}>
                    <TableCell>{v.name}</TableCell>
                    <TableCell className="hidden text-muted-foreground sm:table-cell">
                      {v.geotabDeviceId || "—"}
                    </TableCell>
                    <TableCell>
                      <Badge variant={v.isActive ? "secondary" : "outline"}>
                        {v.isActive ? "Active" : "Inactive"}
                      </Badge>
                    </TableCell>
                    <TableCell className="hidden text-muted-foreground md:table-cell">
                      {formatDateTime(v.lastSyncedAt)}
                    </TableCell>
                  </TableRow>
                ))}
                {!tenant.vehicles.length ? (
                  <TableRow>
                    <TableCell colSpan={4} className="text-muted-foreground">
                      No vehicles yet. Configure MyGeotab and run Sync Vehicles.
                    </TableCell>
                  </TableRow>
                ) : null}
              </TableBody>
            </Table>
          </div>
        </TabsContent>

        <TabsContent value="subscription">
          <Card>
            <CardHeader>
              <CardTitle>Subscription & entitlements</CardTitle>
              <CardDescription>
                MANUAL assignments stay local. STRIPE subscriptions sync from webhooks. Add-in
                access is evaluated server-side via PlanProduct.
              </CardDescription>
            </CardHeader>
            <CardContent className="space-y-4 text-sm">
              {entitlements?.subscription ? (
                <div className="grid gap-3 sm:grid-cols-2">
                  <div>
                    <p className="text-muted-foreground">Current plan</p>
                    <p className="font-medium">
                      {entitlements.subscription.plan.name} ({entitlements.subscription.plan.code})
                    </p>
                  </div>
                  <div>
                    <p className="text-muted-foreground">Subscription status</p>
                    <p className="font-medium">
                      <Badge variant={subscriptionStatusBadgeVariant(entitlements.subscription.status)}>
                        {formatSubscriptionStatus(entitlements.subscription.status)}
                      </Badge>
                    </p>
                  </div>
                  <div>
                    <p className="text-muted-foreground">Subscription source</p>
                    <p className="font-medium">
                      <Badge variant={subscriptionSourceBadgeVariant(entitlements.subscription.source)}>
                        {formatSubscriptionSource(entitlements.subscription.source)}
                      </Badge>
                    </p>
                  </div>
                  <div>
                    <p className="text-muted-foreground">Add-in access</p>
                    <p className="font-medium">{addinAccessLabel(entitlements.products)}</p>
                  </div>
                  <div className="sm:col-span-2">
                    <p className="text-muted-foreground">Entitled products</p>
                    <p className="font-medium">{formatEntitledProducts(entitlements.products)}</p>
                  </div>
                  <div>
                    <p className="text-muted-foreground">Period end</p>
                    <p className="font-medium">
                      {entitlements.subscription.currentPeriodEnd
                        ? new Date(entitlements.subscription.currentPeriodEnd).toLocaleString()
                        : "—"}
                    </p>
                  </div>
                  <div>
                    <p className="text-muted-foreground">Tenant status</p>
                    <p className="font-medium">
                      <StatusBadge
                        variant={tenantStatusBadgeVariant(entitlements.tenantStatus)}
                        indicator={tenantStatusIndicator(entitlements.tenantStatus)}
                      >
                        {formatTenantStatus(entitlements.tenantStatus)}
                      </StatusBadge>
                    </p>
                  </div>
                </div>
              ) : (
                <p className="font-medium">No effective subscription</p>
              )}

              {tenant.subscriptions.length ? (
                <div className="space-y-2 border-t pt-3">
                  <p className="text-xs font-medium uppercase text-muted-foreground">
                    All subscription rows
                  </p>
                  {tenant.subscriptions.map((s) => (
                    <div
                      key={s.id}
                      className="flex flex-wrap items-center gap-2 border-b py-2 last:border-0"
                    >
                      <span className="font-medium">
                        {s.plan.name} ({s.plan.code})
                      </span>
                      <Badge variant={subscriptionStatusBadgeVariant(s.status)}>
                        {formatSubscriptionStatus(s.status)}
                      </Badge>
                      {"source" in s && s.source ? (
                        <Badge variant={subscriptionSourceBadgeVariant(String(s.source))}>
                          {formatSubscriptionSource(String(s.source))}
                        </Badge>
                      ) : null}
                      {"stripeSubscriptionId" in s && s.stripeSubscriptionId ? (
                        <span className="font-mono text-xs text-muted-foreground">
                          {String(s.stripeSubscriptionId)}
                        </span>
                      ) : null}
                    </div>
                  ))}
                </div>
              ) : null}

              <p className="text-xs text-muted-foreground">
                Assign or change MANUAL plans from the Subscriptions API / Plans admin. Stripe IDs
                are operational only — secrets are never shown. Customer Admins cannot grant
                themselves entitlement.
              </p>
            </CardContent>
          </Card>
        </TabsContent>

        <TabsContent value="audit">
          <div className="overflow-hidden rounded-lg border bg-card">
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead>Time</TableHead>
                  <TableHead>Actor</TableHead>
                  <TableHead>Action</TableHead>
                  <TableHead className="hidden md:table-cell">Summary</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {logs.map((log) => (
                  <TableRow key={log.id}>
                    <TableCell className="whitespace-nowrap text-xs text-muted-foreground">
                      {new Date(log.createdAt).toLocaleString()}
                    </TableCell>
                    <TableCell>{log.user?.email || "system"}</TableCell>
                    <TableCell>
                      <Badge variant="outline">{log.action}</Badge>
                    </TableCell>
                    <TableCell className="hidden md:table-cell">{log.summary || "—"}</TableCell>
                  </TableRow>
                ))}
                {!logs.length ? (
                  <TableRow>
                    <TableCell colSpan={4} className="text-muted-foreground">
                      No audit events for this tenant.
                    </TableCell>
                  </TableRow>
                ) : null}
              </TableBody>
            </Table>
          </div>
        </TabsContent>
      </Tabs>
    </>
  );
}
