"use client";

import { Column, ColumnDef } from "@tanstack/react-table";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuLabel,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from "@/app/shadcn_components/ui/dropdown-menu";
import { Button } from "@/app/shadcn_components/ui/button";
import { ArrowUpDown, MoreHorizontal } from "lucide-react";
import { FunnelIcon } from "@heroicons/react/24/outline";
import { formatNumber, getEpcColorClass, sapToEpc } from "@/app/utils";
import { cn } from "@/lib/utils";
import { PropertyWithRelations } from "@/app/db/schema/property";
import { X } from "lucide-react";
import {
  EnumOption,
  TENURE_OPTIONS,
  MAINFUEL_OPTIONS,
} from "@/app/utils/propertyFilters";
import { CurrentEpcTooltip } from "./CurrentEpcTooltip";

/* -----------------------------------------------------------------------
   Helpers
------------------------------------------------------------------------ */
function resolveEnumLabel(
  options: EnumOption[],
  dbValue: string | null | undefined
): string | null {
  if (dbValue == null) return null;
  const opt = options.find((o) => o.dbValues.includes(dbValue));
  return opt?.label ?? dbValue;
}

function tenureBadgeClass(label: string): string {
  if (label.toLowerCase().includes("owner")) return "bg-blue-50 text-blue-700";
  if (label.toLowerCase().includes("private")) return "bg-violet-50 text-violet-700";
  if (label.toLowerCase().includes("social")) return "bg-emerald-50 text-emerald-700";
  return "bg-slate-100 text-slate-500";
}

function Pill({
  children,
  className = "bg-slate-100 text-slate-600",
}: {
  children: React.ReactNode;
  className?: string;
}) {
  return (
    <span
      className={`inline-block px-2 py-0.5 rounded text-[9px] font-bold uppercase tracking-wide whitespace-nowrap ${className}`}
    >
      {children}
    </span>
  );
}

/* -----------------------------------------------------------------------
   EPC letter bubble
------------------------------------------------------------------------ */
const EpcLetterBubble = ({ letter }: { letter: string }) => {
  if (!letter) return <div className="w-5 h-5" />;
  return (
    <div
      className={`inline-flex items-center justify-center w-5 h-5 rounded-full text-xs font-bold text-white ${getEpcColorClass(letter)}`}
    >
      {letter}
    </div>
  );
};

/* -----------------------------------------------------------------------
   Column header with dropdown filter
------------------------------------------------------------------------ */
interface DataTableColumnHeaderProps<TData, TValue>
  extends React.HTMLAttributes<HTMLDivElement> {
  column: Column<TData, TValue>;
  title: string;
}

export function DataTableFilterHeader<TData, TValue>({
  column,
  title,
  className,
  options,
  renderOption,
}: DataTableColumnHeaderProps<TData, TValue> & {
  options: string[];
  renderOption?: (opt: string) => React.ReactNode;
}) {
  const currentValue = column.getFilterValue() as string | undefined;

  return (
    <div className={cn("flex items-center space-x-1", className)}>
      <DropdownMenu>
        <DropdownMenuTrigger asChild>
          <Button
            variant={currentValue ? "secondary" : "ghost"}
            size="sm"
            className={cn(
              "-ml-2 h-8",
              currentValue && "text-accent-foreground bg-accent"
            )}
          >
            <span>{title}</span>
            <FunnelIcon className="ml-2 h-4 w-4" />
          </Button>
        </DropdownMenuTrigger>
        <DropdownMenuContent
          align="start"
          className="max-h-80 overflow-y-auto min-w-[10rem]"
        >
          {options.map((opt) => (
            <DropdownMenuItem
              key={opt}
              onClick={() =>
                column.setFilterValue(currentValue === opt ? undefined : opt)
              }
              className={cn(
                "cursor-pointer flex items-center gap-2 px-2 py-1.5",
                currentValue === opt && "bg-accent"
              )}
            >
              {renderOption ? renderOption(opt) : opt}
            </DropdownMenuItem>
          ))}
        </DropdownMenuContent>
      </DropdownMenu>

      {currentValue && (
        <Button
          variant="ghost"
          className={cn(
            "h-6 w-6 text-gray-500 hover:text-gray-800 transition-opacity duration-150",
            currentValue ? "opacity-100" : "opacity-0 pointer-events-none"
          )}
          onClick={() => column.setFilterValue(undefined)}
          title="Clear filter"
        >
          <X className="h-3.5 w-3.5" />
        </Button>
      )}
    </div>
  );
}

/* -----------------------------------------------------------------------
   Column metadata
------------------------------------------------------------------------ */
export const OPTIONAL_COLUMN_IDS = [
  "propertyType",
  "builtForm",
  "tenure",
  "yearBuilt",
  "totalFloorArea",
  "co2Emissions",
  "mainfuel",
] as const;

export type OptionalColumnId = (typeof OPTIONAL_COLUMN_IDS)[number];

const OPTIONAL_COLUMN_LABELS: Record<OptionalColumnId, string> = {
  propertyType: "Property Type",
  builtForm: "Built Form",
  tenure: "Tenure",
  yearBuilt: "Year Built",
  totalFloorArea: "Floor Area (m²)",
  co2Emissions: "CO₂ Emissions",
  mainfuel: "Main Fuel",
};

export { OPTIONAL_COLUMN_LABELS };

/* -----------------------------------------------------------------------
   Core columns
------------------------------------------------------------------------ */
const coreColumns: ColumnDef<PropertyWithRelations>[] = [
  {
    accessorKey: "address",
    enableGlobalFilter: true,
    header: ({ column }) => (
      <Button
        variant="ghost"
        onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}
      >
        Address
        <ArrowUpDown className="ml-2 h-4 w-4" />
      </Button>
    ),
    cell: ({ row }) => {
      const address = String(row.getValue("address"));
      const postcode = row.original.postcode;
      const propertyId = row.original.id;
      const portfolioId = row.original.portfolioId;

      return (
        <div className="flex flex-col gap-0.5">
          <a
            href={`${portfolioId}/building-passport/${propertyId}`}
            className="text-xs font-bold text-primary hover:text-brandmidblue transition-colors truncate"
          >
            {address}
          </a>
          {postcode && (
            <span className="text-[10px] text-slate-400">{postcode}</span>
          )}
        </div>
      );
    },
  },
  {
    accessorKey: "landlordPropertyId",
    header: () => <div className="text-xs font-medium">Property Ref</div>,
    cell: ({ row }) => (
      <div className="text-gray-700 text-sm">
        {row.original.landlordPropertyId ?? "—"}
      </div>
    ),
  },
  {
    accessorKey: "currentEpc",
    header: () => (
      <div className="flex items-center justify-center gap-1 text-xs">
        Current EPC
        <CurrentEpcTooltip />
      </div>
    ),
    cell: ({ row }) => (
      <div className="text-gray-700 font-medium flex justify-center">
        <EpcLetterBubble letter={row.original.currentEpcRating || ""} />
      </div>
    ),
  },
  {
    accessorKey: "originalSapPoints",
    header: () => (
      <div className="flex justify-center text-xs">Lodged EPC</div>
    ),
    cell: ({ row }) => {
      const originalSap = row.original.originalSapPoints;
      const letter = originalSap ? sapToEpc(originalSap) : null;
      return (
        <div className="text-gray-700 font-medium flex justify-center">
          <EpcLetterBubble letter={letter || ""} />
        </div>
      );
    },
  },
  {
    accessorKey: "targetEpc",
    header: () => (
      <div className="flex justify-center text-xs">Expected EPC</div>
    ),
    cell: ({ row }) => {
      const currentSapPoints = row.original.currentSapPoints || 0;
      const expectedSapPoints = row.original.totalRecommendationSapPoints || 0;

      if (currentSapPoints + expectedSapPoints === 0) {
        return (
          <div className="text-gray-700 font-medium flex justify-center">
            <EpcLetterBubble letter="" />
          </div>
        );
      }
      const expectedEpc = sapToEpc(currentSapPoints + expectedSapPoints);

      return (
        <div className="text-gray-700 font-medium flex justify-center">
          <EpcLetterBubble letter={expectedEpc || ""} />
        </div>
      );
    },
  },
  {
    accessorKey: "epcLodgementDate",
    header: () => (
      <div className="flex justify-center text-xs">EPC Expiry</div>
    ),
    cell: ({ row }) => {
      const dateStr = row.original.epcLodgementDate;
      const expired = row.original.epcIsExpired;

      if (!dateStr) {
        return <div className="text-center text-slate-400 text-xs">—</div>;
      }

      const lodgementDate = new Date(dateStr);
      const expiryDate = new Date(lodgementDate);
      expiryDate.setFullYear(expiryDate.getFullYear() + 10);

      const formatted = expiryDate.toLocaleDateString("en-GB", {
        month: "short",
        year: "numeric",
      });

      if (expired) {
        return (
          <div className="flex flex-col gap-0.5">
            <span className="text-[9px] font-bold text-red-600 bg-red-50 px-1.5 py-0.5 rounded w-max uppercase tracking-wide">
              Expired
            </span>
            <span className="text-[10px] text-slate-400">{formatted}</span>
          </div>
        );
      }

      return (
        <div className="flex flex-col gap-0.5">
          <span className="text-xs font-semibold text-primary">{formatted}</span>
        </div>
      );
    },
  },
  {
    accessorKey: "cost",
    header: () => <div className="flex justify-end text-xs">Plan Cost</div>,
    cell: ({ row }) => {
      const cost = row.original.totalRecommendationCost;
      const creationStatus = row.original.creationStatus;

      if (creationStatus === "LOADING") {
        return <div className="font-medium flex justify-end" />;
      }

      return (
        <div className="text-right">
          {cost ? (
            <span className="text-xs font-bold text-primary">
              £{formatNumber(cost)}
            </span>
          ) : (
            <span className="text-[10px] text-slate-300 italic">No cost</span>
          )}
        </div>
      );
    },
  },
  {
    id: "actions",
    cell: ({ row }) => {
      const property = row.original;
      const propertyId = property.id;
      const portfolioId = property.portfolioId;
      const creationStatus = property.creationStatus;

      if (creationStatus === "LOADING") {
        return (
          <div className="text-gray-700 flex justify-center">Loading...</div>
        );
      }

      return (
        <div className="flex justify-center">
          <DropdownMenu>
            <DropdownMenuTrigger asChild>
              <Button variant="ghost" className="h-8 w-8 p-0">
                <span className="sr-only">Open menu</span>
                <MoreHorizontal className="h-4 w-4" />
              </Button>
            </DropdownMenuTrigger>
            <DropdownMenuContent align="end">
              <DropdownMenuLabel>Actions</DropdownMenuLabel>
              <DropdownMenuItem className="text-gray-700 cursor-pointer">
                <a href={`${portfolioId}/building-passport/${propertyId}`}>
                  Building Passport
                </a>
              </DropdownMenuItem>
              <DropdownMenuItem className="text-gray-700 cursor-pointer">
                Settings
              </DropdownMenuItem>
              <DropdownMenuSeparator />
            </DropdownMenuContent>
          </DropdownMenu>
        </div>
      );
    },
  },
];

/* -----------------------------------------------------------------------
   Optional columns
------------------------------------------------------------------------ */
const optionalColumns: ColumnDef<PropertyWithRelations>[] = [
  {
    id: "propertyType",
    accessorKey: "propertyType",
    header: () => <div className="text-xs">Property Type</div>,
    cell: ({ row }) => {
      const val = row.original.propertyType;
      return val ? <Pill>{val}</Pill> : <span className="text-slate-300 text-xs">—</span>;
    },
  },
  {
    id: "builtForm",
    accessorKey: "builtForm",
    header: () => <div className="text-xs">Built Form</div>,
    cell: ({ row }) => {
      const val = row.original.builtForm;
      return val ? <Pill>{val}</Pill> : <span className="text-slate-300 text-xs">—</span>;
    },
  },
  {
    id: "tenure",
    accessorKey: "tenure",
    header: () => <div className="text-xs">Tenure</div>,
    cell: ({ row }) => {
      const label = resolveEnumLabel(TENURE_OPTIONS, row.original.tenure);
      if (!label) return <span className="text-slate-300 text-xs">—</span>;
      return <Pill className={tenureBadgeClass(label)}>{label}</Pill>;
    },
  },
  {
    id: "yearBuilt",
    accessorKey: "yearBuilt",
    header: () => <div className="text-xs">Year Built</div>,
    cell: ({ row }) => (
      <div className="text-sm text-gray-700">{row.original.yearBuilt ?? "—"}</div>
    ),
  },
  {
    id: "totalFloorArea",
    accessorKey: "totalFloorArea",
    header: () => <div className="text-xs">Floor Area (m²)</div>,
    cell: ({ row }) => {
      const val = row.original.totalFloorArea;
      return (
        <div className="text-sm text-gray-700">
          {val != null ? `${val.toFixed(1)} m²` : "—"}
        </div>
      );
    },
  },
  {
    id: "co2Emissions",
    accessorKey: "co2Emissions",
    header: () => <div className="text-xs">CO₂ Emissions</div>,
    cell: ({ row }) => {
      const val = row.original.co2Emissions;
      return (
        <div className="text-sm text-gray-700">
          {val != null ? `${val.toFixed(1)} kg/m²/yr` : "—"}
        </div>
      );
    },
  },
  {
    id: "mainfuel",
    accessorKey: "mainfuel",
    header: () => <div className="text-xs">Main Fuel</div>,
    cell: ({ row }) => {
      const label = resolveEnumLabel(MAINFUEL_OPTIONS, row.original.mainfuel);
      return label ? <Pill>{label}</Pill> : <span className="text-slate-300 text-xs">—</span>;
    },
  },
];

export const columns: ColumnDef<PropertyWithRelations>[] = [
  ...coreColumns,
  ...optionalColumns,
];
