"use client";

import { useEffect, useState } from "react";
import {
  Check,
  CheckCircle2,
  ChevronLeft,
  ChevronRight,
  Clock3,
  Hourglass,
  Lock,
  RotateCcw,
  Search,
  ShieldCheck,
  User,
  UserCog,
  X,
  XCircle,
} from "lucide-react";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import { cn } from "@/lib/utils";
import { getFixPackageRefundRequestsAction } from "@/features/fixed-packages/actions/booking-actions";
import type {
  FixPackageRefundRequest,
  FixPackageRefundRequestCounts,
} from "@/core/api/services/fix-packages/fix-packages.types";
import { useToastEnhanced } from "@/hooks/use-toast-enhanced";
import { TableSkeleton } from "@/roles/admin/components/table-skeleton";

type StatusFilter = "all" | "pending" | "in-progress" | "approved" | "rejected";

const PER_PAGE = 10;

const cancelledByOptions = [
  { label: "Cancelled By", value: "all" },
  { label: "User", value: "user" },
  { label: "Admin", value: "admin" },
] as const;

const statusMeta: Record<
  string,
  { label: string; icon: typeof Clock3; className: string }
> = {
  pending: {
    label: "Pending",
    icon: Clock3,
    className: "border-border bg-muted/60 text-foreground",
  },
  "in-progress": {
    label: "In Progress",
    icon: Hourglass,
    className: "border-primary/20 bg-primary/10 text-primary",
  },
  approved: {
    label: "Approved",
    icon: CheckCircle2,
    className: "border-primary/20 bg-primary/10 text-primary",
  },
  rejected: {
    label: "Rejected",
    icon: XCircle,
    className: "border-destructive/20 bg-destructive/10 text-destructive",
  },
};

function StatCard({
  title,
  value,
  icon: Icon,
}: {
  title: string;
  value: number;
  icon: typeof Clock3;
}) {
  return (
    <Card className="admin-card border border-border/60 shadow-sm">
      <CardContent className="flex items-center gap-3 p-4">
        <div className="flex h-9 w-9 shrink-0 items-center justify-center rounded-lg bg-primary/10 text-primary">
          <Icon className="h-4 w-4" aria-hidden="true" />
        </div>
        <div className="min-w-0">
          <p className="text-xl font-semibold leading-none text-foreground">
            {value}
          </p>
          <p className="mt-1 truncate text-xs font-medium text-muted-foreground">
            {title}
          </p>
        </div>
      </CardContent>
    </Card>
  );
}

function StatusBadge({ status }: { status: string }) {
  const meta = statusMeta[status] ?? statusMeta["pending"];
  const Icon = meta.icon;

  return (
    <Badge
      variant="outline"
      className={cn("gap-1.5 rounded-full px-3 py-1", meta.className)}
    >
      <Icon className="h-3 w-3" aria-hidden="true" />
      {meta.label}
    </Badge>
  );
}

function CancelledByBadge({ value }: { value: string }) {
  const isAdmin = value === "admin";
  const Icon = isAdmin ? UserCog : User;

  return (
    <Badge
      variant="secondary"
      className="gap-1.5 rounded-full px-3 py-1 text-muted-foreground"
    >
      <Icon className="h-3 w-3" aria-hidden="true" />
      {isAdmin ? "Admin" : "User"}
    </Badge>
  );
}

function getPackageName(request: FixPackageRefundRequest): string {
  const json = request.booking?.fix_package_json;

  if (json) {
    try {
      const parsed = JSON.parse(json) as { name?: unknown };
      if (typeof parsed.name === "string" && parsed.name.trim()) {
        return parsed.name;
      }
    } catch {
      // Fall through to the nested package fallback.
    }
  }

  return request.booking?.fix_package?.name?.trim() || "—";
}

type InitialStats = {
  total: number;
  pending: number;
  inProgress: number;
  approved: number;
  rejected: number;
};

type PaginationData = {
  data: FixPackageRefundRequest[];
  current_page: number;
  last_page: number;
  total: number;
  per_page: number;
  from: number | null;
  to: number | null;
  counts?: FixPackageRefundRequestCounts;
};

const emptyPagination: PaginationData = {
  data: [],
  current_page: 1,
  last_page: 1,
  total: 0,
  per_page: PER_PAGE,
  from: 0,
  to: 0,
};

function normalizePaginationData(data: PaginationData): PaginationData {
  return {
    ...emptyPagination,
    ...data,
    data: Array.isArray(data?.data) ? data.data : [],
  };
}

export function FixPackagesRefundRequestClient({
  initialStats,
  initialData,
}: {
  initialStats: InitialStats;
  initialData: PaginationData;
}) {
  const [searchQuery, setSearchQuery] = useState("");
  const [statusFilter, setStatusFilter] = useState<StatusFilter>("all");
  const [cancelledByFilter, setCancelledByFilter] = useState("all");
  const [currentPage, setCurrentPage] = useState(1);
  const [shouldFetchRequests, setShouldFetchRequests] = useState(false);
  const safeInitialData = normalizePaginationData(initialData);

  const [requests, setRequests] = useState<FixPackageRefundRequest[]>(
    safeInitialData.data
  );
  const [pagination, setPagination] = useState({
    current_page: safeInitialData.current_page,
    last_page: safeInitialData.last_page,
    total: safeInitialData.total,
    per_page: safeInitialData.per_page,
    from: safeInitialData.from ?? 0,
    to: safeInitialData.to ?? 0,
  });
  const [loading, setLoading] = useState(false);

  const { error } = useToastEnhanced();

  useEffect(() => {
    if (!shouldFetchRequests) return;

    let cancelled = false;

    const fetchData = async () => {
      try {
        setLoading(true);
        const data = await getFixPackageRefundRequestsAction({
          page: currentPage,
          per_page: PER_PAGE,
          status: statusFilter === "all" ? undefined : statusFilter,
        });

        if (cancelled) return;

        const safeData = normalizePaginationData(data);
        setRequests(safeData.data);
        setPagination({
          current_page: safeData.current_page,
          last_page: safeData.last_page,
          total: safeData.total,
          per_page: safeData.per_page,
          from: safeData.from ?? 0,
          to: safeData.to ?? 0,
        });
      } catch (err: any) {
        if (cancelled) return;
        error({
          title: "Failed to load refund requests",
          description: err?.message ?? "Please try again.",
        });
      } finally {
        if (!cancelled) setLoading(false);
      }
    };

    fetchData();

    return () => {
      cancelled = true;
    };
  }, [currentPage, shouldFetchRequests, statusFilter]);

  const handleStatusChange = (value: string) => {
    setShouldFetchRequests(true);
    setStatusFilter(value as StatusFilter);
    setCurrentPage(1);
  };

  const resetFilters = () => {
    setSearchQuery("");
    setShouldFetchRequests(true);
    setStatusFilter("all");
    setCancelledByFilter("all");
    setCurrentPage(1);
  };

  const handlePreviousPage = () => {
    setShouldFetchRequests(true);
    setCurrentPage((p) => Math.max(1, p - 1));
  };

  const handleNextPage = () => {
    setShouldFetchRequests(true);
    setCurrentPage((p) => Math.min(pagination.last_page, p + 1));
  };

  const filteredRequests = requests.filter((r) => {
    const query = searchQuery.trim().toLowerCase();
    const matchesSearch =
      !query ||
      String(r.booking_id).toLowerCase().includes(query) ||
      String(r.id).toLowerCase().includes(query) ||
      String(r.booking?.booking_number ?? "")
        .toLowerCase()
        .includes(query) ||
      getPackageName(r).toLowerCase().includes(query);
    const matchesCancelledBy =
      cancelledByFilter === "all" || r.cancelled_by === cancelledByFilter;
    return matchesSearch && matchesCancelledBy;
  });

  const startIndex = (pagination.current_page - 1) * pagination.per_page;

  return (
    <section
      aria-labelledby="fix-packages-refund-heading"
      className="admin-section"
    >
      <header className="admin-page-header">
        <h1 id="fix-packages-refund-heading" className="admin-page-title">
          Fix Packages Refund Request
        </h1>
        <p className="admin-page-description">
          Review and process refund requests submitted for fix package bookings.
        </p>
      </header>

      <div className="grid gap-4 md:grid-cols-2 xl:grid-cols-4">
        <StatCard
          title="Pending Requests"
          value={initialStats.pending}
          icon={Clock3}
        />
        <StatCard
          title="In Progress"
          value={initialStats.inProgress}
          icon={Hourglass}
        />
        <StatCard
          title="Approved"
          value={initialStats.approved}
          icon={ShieldCheck}
        />
        <StatCard
          title="Rejected"
          value={initialStats.rejected}
          icon={XCircle}
        />
      </div>

      <Tabs value={statusFilter} onValueChange={handleStatusChange}>
        <TabsList className="mb-0 h-auto flex-wrap rounded-xl border border-border/50 bg-muted/50 p-1.5">
          {(
            [
              { value: "all", label: `All (${initialStats.total})` },
              { value: "pending", label: `Pending (${initialStats.pending})` },
              {
                value: "in-progress",
                label: `In Progress (${initialStats.inProgress})`,
              },
              {
                value: "approved",
                label: `Approved (${initialStats.approved})`,
              },
              {
                value: "rejected",
                label: `Rejected (${initialStats.rejected})`,
              },
            ] as const
          ).map((tab) => (
            <TabsTrigger
              key={tab.value}
              value={tab.value}
              className="rounded-lg px-4 py-2 data-[state=active]:bg-background data-[state=active]:shadow-sm"
            >
              {tab.label}
            </TabsTrigger>
          ))}
        </TabsList>
      </Tabs>

      <Card className="admin-card border-0 shadow-sm">
        <CardContent className="p-4">
          <div className="grid gap-3 lg:grid-cols-[1fr_180px_auto]">
            <div className="relative">
              <Search
                className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground"
                aria-hidden="true"
              />
              <Input
                value={searchQuery}
                onChange={(e) => setSearchQuery(e.target.value)}
                placeholder="Search by package name, booking number..."
                className="h-11 pl-10"
                aria-label="Search refund requests"
              />
            </div>

            <Select
              value={cancelledByFilter}
              onValueChange={setCancelledByFilter}
            >
              <SelectTrigger
                className="h-11"
                aria-label="Filter by cancelled by"
              >
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                {cancelledByOptions.map((option) => (
                  <SelectItem key={option.value} value={option.value}>
                    {option.label}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>

            <Button
              type="button"
              variant="secondary"
              className="h-11 gap-2"
              onClick={resetFilters}
            >
              <RotateCcw className="h-4 w-4" aria-hidden="true" />
              Reset
            </Button>
          </div>
        </CardContent>
      </Card>

      <Card className="admin-card overflow-hidden border-0 shadow-sm">
        <div className="overflow-x-auto">
          {loading ? (
            <TableSkeleton rows={PER_PAGE} columns={6} />
          ) : (
            <Table>
              <TableHeader>
                <TableRow className="bg-muted/40 hover:bg-muted/40">
                  <TableHead className="w-20">S.No</TableHead>
                  <TableHead>Package Name</TableHead>
                  <TableHead>Booking Number</TableHead>
                  <TableHead>Status</TableHead>
                  <TableHead>Cancelled By</TableHead>
                  <TableHead>Reject Reason</TableHead>
                  <TableHead className="min-w-44">Action</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {filteredRequests.length === 0 ? (
                  <TableRow>
                    <TableCell colSpan={7} className="h-32 text-center">
                      <p className="font-medium">No refund requests found</p>
                      <p className="mt-1 text-sm text-muted-foreground">
                        Try adjusting the search or status filters.
                      </p>
                    </TableCell>
                  </TableRow>
                ) : (
                  filteredRequests.map((request, index) => (
                    <TableRow key={request.id}>
                      <TableCell className="font-medium text-muted-foreground">
                        {startIndex + index + 1}
                      </TableCell>
                      <TableCell>
                        <p className="max-w-72 whitespace-normal font-semibold text-foreground">
                          {getPackageName(request)}
                        </p>
                      </TableCell>
                      <TableCell>
                        <span className="font-medium text-foreground">
                          {request.booking?.booking_number ?? "—"}
                        </span>
                      </TableCell>
                      <TableCell>
                        <StatusBadge status={request.status} />
                      </TableCell>
                      <TableCell>
                        <CancelledByBadge value={request.cancelled_by} />
                      </TableCell>
                      <TableCell>
                        <p className="max-w-72 whitespace-normal text-sm text-muted-foreground">
                          {request.reject_reason?.trim() || "—"}
                        </p>
                      </TableCell>
                      <TableCell>
                        {request.status === "pending" ? (
                          <Button className="h-9 px-4">In Review</Button>
                        ) : request.status === "in-progress" ? (
                          <div className="flex flex-wrap gap-2">
                            <Button className="h-9 gap-1 px-4">
                              <Check className="h-4 w-4" aria-hidden="true" />
                              Approve
                            </Button>
                            <Button
                              variant="destructive"
                              className="h-9 gap-1 px-4"
                            >
                              <X className="h-4 w-4" aria-hidden="true" />
                              Reject
                            </Button>
                          </div>
                        ) : (
                          <Badge
                            variant="secondary"
                            className="gap-1.5 rounded-full px-3 py-2 text-muted-foreground"
                          >
                            <Lock className="h-3 w-3" aria-hidden="true" />
                            Request Closed
                          </Badge>
                        )}
                      </TableCell>
                    </TableRow>
                  ))
                )}
              </TableBody>
            </Table>
          )}
        </div>

        {pagination.last_page > 1 && (
          <div className="flex items-center justify-between border-t border-border/50 px-4 py-3">
            <p className="text-sm text-muted-foreground">
              Showing {pagination.from}–{pagination.to} of {pagination.total}{" "}
              results
            </p>
            <div className="flex items-center gap-2">
              <Button
                variant="outline"
                size="sm"
                className="h-8 gap-1"
                disabled={currentPage <= 1 || loading}
                onClick={handlePreviousPage}
              >
                <ChevronLeft className="h-4 w-4" />
                Previous
              </Button>
              <span className="text-sm text-muted-foreground">
                Page {pagination.current_page} of {pagination.last_page}
              </span>
              <Button
                variant="outline"
                size="sm"
                className="h-8 gap-1"
                disabled={currentPage >= pagination.last_page || loading}
                onClick={handleNextPage}
              >
                Next
                <ChevronRight className="h-4 w-4" />
              </Button>
            </div>
          </div>
        )}
      </Card>
    </section>
  );
}
