"use client";

import { useEffect, useMemo, useState } from "react";
import Link from "next/link";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
import { getFixPackageBookingsAction } from "@/features/fixed-packages/actions/booking-actions";
import {
  getUserVehicleBookingsAction,
  type UserVehicleBooking,
} from "@/features/booking/actions/vehicle-bookings-actions";
import type { FixPackageBooking } from "@/core/api/services/fix-packages/fix-packages.types";
import { cn } from "@/lib/utils";
import {
  Box,
  CalendarDays,
  Car,
  Clock3,
  Loader2,
  PieChart,
  Plus,
} from "lucide-react";

type DashboardBooking = {
  id: string;
  type: "fixed" | "vehicle";
  title: string;
  date: Date | null;
  status: string;
  reference: string;
};

function parseDate(value: string | null | undefined) {
  if (!value) return null;
  const date = new Date(value);
  return Number.isNaN(date.getTime()) ? null : date;
}

function isSameDay(a: Date, b: Date) {
  return (
    a.getFullYear() === b.getFullYear() &&
    a.getMonth() === b.getMonth() &&
    a.getDate() === b.getDate()
  );
}

function formatShortDate(date: Date | null) {
  if (!date) return "Date not set";
  return new Intl.DateTimeFormat("en-IN", {
    day: "2-digit",
    month: "short",
    year: "numeric",
  }).format(date);
}

function formatStatus(value: string | null | undefined) {
  if (!value) return "Pending";
  if (value === "confirm") return "Confirmed";
  if (value === "cancel") return "Cancelled";
  return value.replace(/_/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
}

function normalizeStatus(value: string | null | undefined) {
  const status = (value ?? "pending").toLowerCase();
  if (status === "confirm" || status === "booked") return "confirmed";
  if (status === "complete") return "completed";
  if (status === "cancel") return "cancelled";
  return status;
}

function readFixedPackageTitle(booking: FixPackageBooking) {
  if (booking.fix_package?.name) return booking.fix_package.name;
  if (typeof booking.fix_package_json === "string" && booking.fix_package_json) {
    try {
      const parsed = JSON.parse(booking.fix_package_json) as { name?: string };
      if (parsed.name) return parsed.name;
    } catch {
      return "Fixed Package";
    }
  }
  return "Fixed Package";
}

function readVehicleTitle(booking: UserVehicleBooking) {
  const snapshot =
    typeof booking.vehicle_booking_json === "string"
      ? (() => {
          try {
            return JSON.parse(booking.vehicle_booking_json) as {
              vehicle?: { name?: string | null };
            };
          } catch {
            return null;
          }
        })()
      : booking.vehicle_booking_json;

  return (
    booking.vehicle?.name ??
    snapshot?.vehicle?.name ??
    booking.booking_number ??
    "Vehicle Booking"
  );
}

function countByStatus(items: Array<{ status?: string | null }>) {
  return items.reduce(
    (acc, item) => {
      const status = normalizeStatus(item.status);
      acc.total += 1;
      if (status in acc) acc[status as keyof typeof acc] += 1;
      return acc;
    },
    {
      total: 0,
      pending: 0,
      confirmed: 0,
      completed: 0,
      cancelled: 0,
    }
  );
}

function getMonthLabel(date: Date) {
  return new Intl.DateTimeFormat("en-IN", { month: "short" }).format(date);
}

function getMonthKey(date: Date) {
  return `${date.getFullYear()}-${date.getMonth()}`;
}

function buildTrend(
  fixedBookings: FixPackageBooking[],
  vehicleBookings: UserVehicleBooking[]
) {
  const now = new Date();
  const months = Array.from({ length: 6 }, (_, index) => {
    const date = new Date(now.getFullYear(), now.getMonth() - 5 + index, 1);
    return {
      key: getMonthKey(date),
      label: getMonthLabel(date),
      fixed: 0,
      vehicle: 0,
    };
  });

  fixedBookings.forEach((booking) => {
    const date = parseDate(booking.start_date);
    if (!date) return;
    const item = months.find((month) => month.key === getMonthKey(date));
    if (item) item.fixed += 1;
  });

  vehicleBookings.forEach((booking) => {
    const date = parseDate(booking.start_date);
    if (!date) return;
    const item = months.find((month) => month.key === getMonthKey(date));
    if (item) item.vehicle += 1;
  });

  return months;
}

function chartPath(values: number[], width = 620, height = 210) {
  const max = Math.max(1, ...values);
  const step = width / Math.max(1, values.length - 1);
  return values
    .map((value, index) => {
      const x = index * step;
      const y = height - (value / max) * (height - 34) - 18;
      return `${index === 0 ? "M" : "L"}${x.toFixed(1)},${y.toFixed(1)}`;
    })
    .join(" ");
}

function MetricCard({
  label,
  value,
  delta,
  icon: Icon,
}: {
  label: string;
  value: number;
  delta: string;
  icon: typeof CalendarDays;
}) {
  return (
    <Card className="border-0 bg-white shadow-sm">
      <CardContent className="flex items-center justify-between gap-4 px-5 py-4">
        <div>
          <p className="text-sm font-semibold text-slate-500">{label}</p>
          <div className="mt-1 flex items-baseline gap-2">
            <p className="text-2xl font-bold leading-none text-[#0c1934]">
              {value}
            </p>
            <p className="text-sm font-bold text-teal-600">{delta}</p>
          </div>
        </div>
        <div className="flex h-12 w-12 items-center justify-center rounded-xl bg-gradient-to-br from-[#0c1934] to-[#022f47] text-white shadow-md">
          <Icon className="h-5 w-5" />
        </div>
      </CardContent>
    </Card>
  );
}

export function UserDashboardContent() {
  const [userName, setUserName] = useState("User");
  const [fixedBookings, setFixedBookings] = useState<FixPackageBooking[]>([]);
  const [vehicleBookings, setVehicleBookings] = useState<UserVehicleBooking[]>(
    []
  );
  const [isLoading, setIsLoading] = useState(true);

  useEffect(() => {
    const customerSession = sessionStorage.getItem("customer_session");
    if (customerSession) {
      try {
        const session = JSON.parse(customerSession) as {
          name?: string;
          first_name?: string;
        };
        setUserName(session.name || session.first_name || "User");
      } catch {
        setUserName("User");
      }
    }

    let active = true;

    (async () => {
      setIsLoading(true);
      const [fixedResult, vehicleResult] = await Promise.allSettled([
        getFixPackageBookingsAction({ page: 1, per_page: 100 }),
        getUserVehicleBookingsAction({ page: 1, per_page: 100 }),
      ]);

      if (!active) return;

      if (fixedResult.status === "fulfilled") {
        setFixedBookings(fixedResult.value.bookings ?? []);
      }
      if (
        vehicleResult.status === "fulfilled" &&
        vehicleResult.value.success &&
        vehicleResult.value.data
      ) {
        setVehicleBookings(vehicleResult.value.data.data ?? []);
      }

      setIsLoading(false);
    })();

    return () => {
      active = false;
    };
  }, []);

  const dashboardBookings = useMemo<DashboardBooking[]>(() => {
    const fixed = fixedBookings.map((booking) => ({
      id: `fixed-${booking.id}`,
      type: "fixed" as const,
      title: readFixedPackageTitle(booking),
      date: parseDate(booking.start_date),
      status: booking.booking_status ?? booking.status ?? "pending",
      reference: booking.booking_number,
    }));

    const vehicles = vehicleBookings.map((booking) => ({
      id: `vehicle-${booking.id}`,
      type: "vehicle" as const,
      title: readVehicleTitle(booking),
      date: parseDate(booking.start_date),
      status: booking.booking_status ?? "pending",
      reference: booking.booking_number ?? `VB-${booking.id}`,
    }));

    return [...fixed, ...vehicles].sort((a, b) => {
      const aTime = a.date?.getTime() ?? Number.MAX_SAFE_INTEGER;
      const bTime = b.date?.getTime() ?? Number.MAX_SAFE_INTEGER;
      return aTime - bTime;
    });
  }, [fixedBookings, vehicleBookings]);

  const today = new Date();
  const todayStart = new Date(
    today.getFullYear(),
    today.getMonth(),
    today.getDate()
  );
  const todayBookings = dashboardBookings.filter(
    (booking) => booking.date && isSameDay(booking.date, today)
  );
  const upcomingBookings = dashboardBookings.filter(
    (booking) => booking.date && booking.date >= todayStart
  );
  const fixedStats = countByStatus(
    fixedBookings.map((booking) => ({ status: booking.booking_status }))
  );
  const vehicleStats = countByStatus(
    vehicleBookings.map((booking) => ({ status: booking.booking_status }))
  );
  const trend = buildTrend(fixedBookings, vehicleBookings);
  const fixedTrend = trend.map((item) => item.fixed);
  const vehicleTrend = trend.map((item) => item.vehicle);
  const totalBookings = fixedStats.total + vehicleStats.total;
  const confirmedTotal = fixedStats.confirmed + vehicleStats.confirmed;
  const pendingTotal = fixedStats.pending + vehicleStats.pending;
  const cancelledTotal = fixedStats.cancelled + vehicleStats.cancelled;
  const completionPercent =
    totalBookings > 0 ? Math.round((confirmedTotal / totalBookings) * 100) : 0;
  const fixedShare =
    totalBookings > 0 ? Math.round((fixedStats.total / totalBookings) * 100) : 0;

  const metricCards = [
    {
      label: "Total Bookings",
      value: totalBookings,
      delta: `${upcomingBookings.length} upcoming`,
      icon: CalendarDays,
    },
    {
      label: "Vehicles",
      value: vehicleStats.total,
      delta: `${vehicleStats.confirmed} confirmed`,
      icon: Car,
    },
    {
      label: "Fix Packages",
      value: fixedStats.total,
      delta: `${fixedStats.pending} pending`,
      icon: Box,
    },
    {
      label: "Today",
      value: todayBookings.length,
      delta: "bookings today",
      icon: Clock3,
    },
  ];

  const barStats = [
    { label: "Fix Pending", value: fixedStats.pending },
    { label: "Fix Confirmed", value: fixedStats.confirmed },
    { label: "Fix Cancelled", value: fixedStats.cancelled },
    { label: "Vehicle Pending", value: vehicleStats.pending },
    { label: "Vehicle Confirmed", value: vehicleStats.confirmed },
    { label: "Vehicle Cancelled", value: vehicleStats.cancelled },
  ];
  const maxBarValue = Math.max(1, ...barStats.map((item) => item.value));

  return (
    <div className="space-y-6">
      <div>
        <h1 className="text-3xl font-bold text-[#0c1934]">
          Hello, {userName}
        </h1>
        <p className="mt-1 text-sm text-gray-500">
          Today is{" "}
          {new Intl.DateTimeFormat("en-IN", {
            weekday: "long",
            day: "2-digit",
            month: "long",
            year: "numeric",
          }).format(today)}
        </p>
      </div>

      <div className="grid gap-4 md:grid-cols-2 xl:grid-cols-4">
        {metricCards.map(({ label, value, delta, icon }) => (
          <MetricCard
            key={label}
            label={label}
            value={isLoading ? 0 : value}
            delta={delta}
            icon={icon}
          />
        ))}
      </div>

      <div className="grid gap-6 xl:grid-cols-[1fr_1fr]">
        <Card className="border-border/50 shadow-sm">
          <CardContent className="p-5">
            <div className="mb-5 flex items-center justify-between">
              <div>
                <h2 className="text-lg font-bold text-[#0c1934]">
                  Chart Summary
                </h2>
                <p className="text-sm text-gray-500">
                  Booking split and current activity
                </p>
              </div>
              <PieChart className="h-5 w-5 text-teal-700" />
            </div>

            <div className="grid gap-6 md:grid-cols-[220px_1fr] md:items-center">
              <div className="relative mx-auto h-52 w-52">
                <div
                  className="h-full w-full rounded-full"
                  style={{
                    background: `conic-gradient(#14b8a6 0 ${fixedShare}%, #f84200 ${fixedShare}% 100%)`,
                  }}
                />
                <div className="absolute inset-8 flex flex-col items-center justify-center rounded-full bg-white text-center shadow-inner">
                  <p className="text-3xl font-bold text-[#0c1934]">
                    {completionPercent}%
                  </p>
                  <p className="text-xs text-gray-500">confirmed</p>
                </div>
              </div>

              <div className="space-y-4">
                <div className="grid grid-cols-2 gap-3">
                  <div className="rounded-xl bg-teal-50 p-4">
                    <p className="text-xs text-gray-500">Fix Packages</p>
                    <p className="mt-1 text-2xl font-bold text-teal-700">
                      {fixedStats.total}
                    </p>
                  </div>
                  <div className="rounded-xl bg-orange-50 p-4">
                    <p className="text-xs text-gray-500">Vehicles</p>
                    <p className="mt-1 text-2xl font-bold text-[#f84200]">
                      {vehicleStats.total}
                    </p>
                  </div>
                  <div className="rounded-xl bg-amber-50 p-4">
                    <p className="text-xs text-gray-500">Pending</p>
                    <p className="mt-1 text-2xl font-bold text-amber-600">
                      {pendingTotal}
                    </p>
                  </div>
                  <div className="rounded-xl bg-red-50 p-4">
                    <p className="text-xs text-gray-500">Cancelled</p>
                    <p className="mt-1 text-2xl font-bold text-red-600">
                      {cancelledTotal}
                    </p>
                  </div>
                </div>
              </div>
            </div>
          </CardContent>
        </Card>

        <Card className="border-border/50 shadow-sm">
          <CardContent className="p-5">
            <div className="mb-5 flex items-center justify-between">
              <div>
                <h2 className="text-lg font-bold text-[#0c1934]">
                  Status Overview
                </h2>
                <p className="text-sm text-gray-500">
                  Counts by package and vehicle status
                </p>
              </div>
              <Badge className="bg-teal-50 text-teal-700 hover:bg-teal-50">
                {totalBookings} total
              </Badge>
            </div>
            <div className="grid min-h-64 grid-cols-6 items-end gap-3">
              {barStats.map((item, index) => (
                <div key={item.label} className="flex flex-col items-center gap-2">
                  <div className="flex h-44 w-full items-end justify-center rounded-xl bg-teal-50/60 px-2 py-2">
                    <div
                      className={cn(
                        "w-full rounded-lg",
                        index < 3
                          ? "bg-gradient-to-t from-teal-700 to-teal-400"
                          : "bg-gradient-to-t from-[#0c1934] to-[#022f47]"
                      )}
                      style={{
                        height: `${Math.max(8, (item.value / maxBarValue) * 100)}%`,
                      }}
                    />
                  </div>
                  <p className="text-center text-[11px] font-medium leading-tight text-gray-500">
                    {item.label}
                  </p>
                  <p className="text-sm font-bold text-[#0c1934]">
                    {item.value}
                  </p>
                </div>
              ))}
            </div>
          </CardContent>
        </Card>
      </div>

      <div className="grid gap-6 xl:grid-cols-2">
        <Card className="border-border/50 shadow-sm">
          <CardContent className="p-5">
            <div className="mb-5 flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
              <div>
                <h2 className="text-lg font-bold text-[#0c1934]">
                  Booking Requests
                </h2>
                <p className="text-sm text-gray-500">
                  Fixed package and vehicle bookings over the last six months
                </p>
              </div>
              <div className="flex gap-3 text-xs font-medium">
                <span className="flex items-center gap-2">
                  <span className="h-2.5 w-2.5 rounded-full bg-teal-500" />
                  Fix Packages
                </span>
                <span className="flex items-center gap-2">
                  <span className="h-2.5 w-2.5 rounded-full bg-[#f84200]" />
                  Vehicles
                </span>
              </div>
            </div>
            <div className="overflow-hidden rounded-2xl bg-gradient-to-br from-teal-50/70 to-white p-4">
              <svg viewBox="0 0 620 250" className="h-72 w-full">
                {[0, 1, 2, 3].map((line) => (
                  <line
                    key={line}
                    x1="0"
                    x2="620"
                    y1={30 + line * 55}
                    y2={30 + line * 55}
                    stroke="#dbeafe"
                    strokeDasharray="4 8"
                  />
                ))}
                <path
                  d={chartPath(fixedTrend, 620, 210)}
                  fill="none"
                  stroke="#14b8a6"
                  strokeLinecap="round"
                  strokeLinejoin="round"
                  strokeWidth="3"
                />
                <path
                  d={chartPath(vehicleTrend, 620, 210)}
                  fill="none"
                  stroke="#f84200"
                  strokeLinecap="round"
                  strokeLinejoin="round"
                  strokeWidth="3"
                />
                {trend.map((item, index) => (
                  <text
                    key={item.key}
                    x={index * (620 / Math.max(1, trend.length - 1))}
                    y="242"
                    textAnchor={index === 0 ? "start" : "middle"}
                    className="fill-gray-500 text-[12px]"
                  >
                    {item.label}
                  </text>
                ))}
              </svg>
            </div>
          </CardContent>
        </Card>

        <Card className="border-border/50 shadow-sm">
          <CardContent className="p-5">
            <div className="mb-4 flex items-center justify-between">
              <h2 className="text-lg font-bold text-[#0c1934]">
                Upcoming Bookings
              </h2>
              <CalendarDays className="h-5 w-5 text-teal-700" />
            </div>
            {isLoading ? (
              <Loader2 className="h-5 w-5 animate-spin text-teal-600" />
            ) : upcomingBookings.length === 0 ? (
              <div className="flex min-h-[300px] flex-col items-center justify-center rounded-2xl border border-dashed border-teal-200 bg-gradient-to-br from-teal-50 via-white to-cyan-50 p-6 text-center">
                <div className="flex h-16 w-16 items-center justify-center rounded-2xl bg-gradient-to-br from-[#0c1934] to-[#022f47] text-white shadow-md">
                  <CalendarDays className="h-8 w-8" />
                </div>
                <h3 className="mt-5 text-lg font-bold text-[#0c1934]">
                  No upcoming bookings yet
                </h3>
                <p className="mt-2 max-w-sm text-sm leading-6 text-gray-500">
                  Your future vehicle trips and fixed package journeys will show
                  up here once they are booked.
                </p>
                <Button
                  asChild
                  className="mt-5 gap-2 rounded-xl bg-gradient-to-r from-teal-600 to-cyan-600 px-5 font-bold text-white shadow-md hover:from-teal-700 hover:to-cyan-700"
                >
                  <Link href="/vehicle-booking">
                    <Plus className="h-4 w-4" />
                    Book a Trip
                  </Link>
                </Button>
              </div>
            ) : (
              <div className="grid gap-3">
                {upcomingBookings.slice(0, 6).map((booking) => (
                  <div
                    key={booking.id}
                    className="flex gap-3 rounded-xl border border-border/50 bg-white p-4"
                  >
                    <span
                      className={cn(
                        "mt-1 h-12 w-1 rounded-full",
                        booking.type === "fixed"
                          ? "bg-teal-500"
                          : "bg-[#f84200]"
                      )}
                    />
                    <div className="min-w-0 flex-1">
                      <p className="text-xs font-medium text-gray-500">
                        {formatShortDate(booking.date)}
                      </p>
                      <p className="mt-1 truncate font-semibold text-[#0c1934]">
                        {booking.title}
                      </p>
                      <div className="mt-2 flex items-center gap-2">
                        <Badge variant="outline" className="bg-white text-xs">
                          {booking.type === "fixed" ? "Fix Package" : "Vehicle"}
                        </Badge>
                        <Badge variant="outline" className="bg-white text-xs">
                          {formatStatus(booking.status)}
                        </Badge>
                      </div>
                    </div>
                  </div>
                ))}
              </div>
            )}
          </CardContent>
        </Card>
      </div>
    </div>
  );
}
