"use client";

import * as React from "react";
import { Plus, Trash2 } from "lucide-react";
import { Controller, type Control, type UseFormRegister } from "react-hook-form";
import { useFieldArray } from "react-hook-form";

import { Button } from "@/components/ui/button";
import { DatePicker } from "@/components/date-range-picker";
import { formDatePickerClass } from "@/components/form/common/form-layout";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import { cn } from "@/lib/utils";

import { NON_CALL_OPTIONS, type StructureFormValues } from "./schema";

function useDuplicateDates(dates: string[]) {
  return React.useMemo(() => {
    const seen = new Set<string>();
    const duplicates = new Set<string>();
    for (const date of dates) {
      const trimmed = date.trim();
      if (!trimmed) continue;
      if (seen.has(trimmed)) {
        duplicates.add(trimmed);
      } else {
        seen.add(trimmed);
      }
    }
    return duplicates;
  }, [dates]);
}

type ObservationTableProps = {
  control: Control<StructureFormValues>;
  register: UseFormRegister<StructureFormValues>;
  dates: string[];
};

export function StructureObservationTable({
  control,
  register,
  dates,
}: ObservationTableProps) {
  const { fields, append, remove } = useFieldArray({
    control,
    name: "observationDates",
  });
  const duplicates = useDuplicateDates(dates);

  const removeDuplicates = () => {
    const seen = new Set<string>();
    const indicesToRemove: number[] = [];
    dates.forEach((date, index) => {
      const trimmed = date.trim();
      if (!trimmed) return;
      if (seen.has(trimmed)) {
        indicesToRemove.push(index);
      } else {
        seen.add(trimmed);
      }
    });
    [...indicesToRemove].reverse().forEach((index) => remove(index));
  };

  return (
    <ChildTableShell
      title="Observation dates"
      subtitle="structure_observation_child"
      onAdd={() => append({ date: "", nonCall: "N" })}
      showRemoveDuplicates={duplicates.size > 0}
      onRemoveDuplicates={removeDuplicates}
      removeDuplicatesLabel="Remove duplicate rows"
    >
      <Table>
        <TableHeader>
          <TableRow>
            <TableHead className="w-16">Sl no</TableHead>
            <TableHead>Date</TableHead>
            <TableHead className="w-28">Non call</TableHead>
            <TableHead className="w-20" />
          </TableRow>
        </TableHeader>
        <TableBody>
          {fields.length === 0 ? (
            <TableRow>
              <TableCell colSpan={4} className="text-muted-foreground text-sm">
                No observation rows. Use Add row to create dates.
              </TableCell>
            </TableRow>
          ) : (
            fields.map((field, index) => {
              const dateValue = dates[index] ?? "";
              const isDuplicate = dateValue.trim() && duplicates.has(dateValue.trim());
              return (
                <TableRow key={field.id}>
                  <TableCell className="text-muted-foreground text-sm">{index + 1}</TableCell>
                  <TableCell>
                    <Controller
                      control={control}
                      name={`observationDates.${index}.date`}
                      render={({ field }) => (
                        <DatePicker
                          value={field.value ?? ""}
                          onChange={field.onChange}
                          placeholder="Select date"
                          className={cn(
                            formDatePickerClass,
                            "h-8",
                            isDuplicate && "border-destructive bg-destructive/10",
                          )}
                        />
                      )}
                    />
                  </TableCell>
                  <TableCell>
                    <select
                      className="flex h-8 w-full rounded-md border border-input bg-background px-2 text-sm shadow-xs"
                      {...register(`observationDates.${index}.nonCall`)}
                    >
                      {NON_CALL_OPTIONS.map((value) => (
                        <option key={value} value={value}>
                          {value}
                        </option>
                      ))}
                    </select>
                  </TableCell>
                  <TableCell>
                    <Button
                      type="button"
                      variant="ghost"
                      size="icon-sm"
                      className="text-destructive"
                      onClick={() => remove(index)}
                      aria-label="Remove row"
                    >
                      <Trash2 className="size-3.5" />
                    </Button>
                  </TableCell>
                </TableRow>
              );
            })
          )}
        </TableBody>
      </Table>
    </ChildTableShell>
  );
}

type CouponTableProps = {
  control: Control<StructureFormValues>;
  register: UseFormRegister<StructureFormValues>;
  dates: string[];
};

export function StructureCouponTable({ control, register, dates }: CouponTableProps) {
  const { fields, append, remove } = useFieldArray({
    control,
    name: "couponDates",
  });
  const duplicates = useDuplicateDates(dates);

  const removeDuplicates = () => {
    const seen = new Set<string>();
    const indicesToRemove: number[] = [];
    dates.forEach((date, index) => {
      const trimmed = date.trim();
      if (!trimmed) return;
      if (seen.has(trimmed)) {
        indicesToRemove.push(index);
      } else {
        seen.add(trimmed);
      }
    });
    [...indicesToRemove].reverse().forEach((index) => remove(index));
  };

  return (
    <ChildTableShell
      title="Coupon dates"
      subtitle="structure_coupon_child"
      onAdd={() => append({ date: "" })}
      showRemoveDuplicates={duplicates.size > 0}
      onRemoveDuplicates={removeDuplicates}
      removeDuplicatesLabel="Remove duplicate coupons"
    >
      <Table>
        <TableHeader>
          <TableRow>
            <TableHead className="w-16">Sl no</TableHead>
            <TableHead>Date</TableHead>
            <TableHead className="w-20" />
          </TableRow>
        </TableHeader>
        <TableBody>
          {fields.length === 0 ? (
            <TableRow>
              <TableCell colSpan={3} className="text-muted-foreground text-sm">
                No coupon rows. Use Add row to create dates.
              </TableCell>
            </TableRow>
          ) : (
            fields.map((field, index) => {
              const dateValue = dates[index] ?? "";
              const isDuplicate = dateValue.trim() && duplicates.has(dateValue.trim());
              return (
                <TableRow key={field.id}>
                  <TableCell className="text-muted-foreground text-sm">{index + 1}</TableCell>
                  <TableCell>
                    <Controller
                      control={control}
                      name={`couponDates.${index}.date`}
                      render={({ field }) => (
                        <DatePicker
                          value={field.value ?? ""}
                          onChange={field.onChange}
                          placeholder="Select date"
                          className={cn(
                            formDatePickerClass,
                            "h-8",
                            isDuplicate && "border-destructive bg-destructive/10",
                          )}
                        />
                      )}
                    />
                  </TableCell>
                  <TableCell>
                    <Button
                      type="button"
                      variant="ghost"
                      size="icon-sm"
                      className="text-destructive"
                      onClick={() => remove(index)}
                      aria-label="Remove row"
                    >
                      <Trash2 className="size-3.5" />
                    </Button>
                  </TableCell>
                </TableRow>
              );
            })
          )}
        </TableBody>
      </Table>
    </ChildTableShell>
  );
}

function ChildTableShell({
  title,
  subtitle,
  children,
  onAdd,
  showRemoveDuplicates,
  onRemoveDuplicates,
  removeDuplicatesLabel,
}: {
  title: string;
  subtitle: string;
  children: React.ReactNode;
  onAdd: () => void;
  showRemoveDuplicates: boolean;
  onRemoveDuplicates: () => void;
  removeDuplicatesLabel: string;
}) {
  return (
    <div className="space-y-3">
      <div className="flex flex-wrap items-center justify-between gap-2">
        <div>
          <h4 className="font-semibold text-sm">{title}</h4>
          <p className="text-muted-foreground text-xs">({subtitle})</p>
        </div>
        <Button type="button" variant="outline" size="sm" className="gap-1.5" onClick={onAdd}>
          <Plus className="size-3.5" />
          Add row
        </Button>
      </div>
      <div className="overflow-x-auto rounded-md border">{children}</div>
      {showRemoveDuplicates ? (
        <Button type="button" variant="secondary" size="sm" onClick={onRemoveDuplicates}>
          {removeDuplicatesLabel}
        </Button>
      ) : null}
    </div>
  );
}
