import React, { useEffect, useState } from "react";
import {
  Button,
  Card,
  Form,
  Input,
  InputNumber,
  Pagination,
  Radio,
  Select,
  Switch,
  Table,
  Tag,
} from "antd";
import { Edit, Hash, Plus, Search } from "lucide-react";
import {
  Controller,
  Resolver,
  SubmitHandler,
  useForm,
  useWatch,
} from "react-hook-form";
import { yupResolver } from "@hookform/resolvers/yup";
import type { ColumnsType } from "antd/es/table";
import * as yup from "yup";
import toast from "react-hot-toast";
import { API_Instance } from "@/api/axios.instance";
import API_Constants from "@/constants/api.constants";
import Modal from "@/components/shared/Modal";
import { useDebounce } from "@/hooks/useDebounce";
import { getAxiosErrorMessage } from "@/utils/index.utils";
import { IReferenceSequence } from "@/types";
import dayjs from "dayjs";

type CountFromOption = "NEW" | "CONTINUE";

type SequenceFormValues = Pick<
  IReferenceSequence,
  "type" | "prefix" | "lastCount" | "isActive"
> & {
  countFrom: CountFromOption;
};

const schema = yup.object({
  type: yup.string().trim(),
  prefix: yup.string().trim().required("Prefix is required"),
  lastCount: yup
    .number()
    .typeError("Last count is required")
    .integer("Last count must be a whole number")
    .min(0, "Last count cannot be negative")
    .required("Last count is required"),
  isActive: yup.boolean().required(),
  countFrom: yup
    .mixed<CountFromOption>()
    .oneOf(["NEW", "CONTINUE"], "Select a valid count option")
    .required("Count option is required"),
});

const ReferenceSequencesPage: React.FC = () => {
  const [sequences, setSequences] = useState<IReferenceSequence[]>([]);
  const [loading, setLoading] = useState(false);
  const [isModalOpen, setIsModalOpen] = useState(false);
  const [editingSequence, setEditingSequence] =
    useState<IReferenceSequence | null>(null);
  const [search, setSearch] = useState("");
  const [status, setStatus] = useState("");
  const [page, setPage] = useState(1);
  const [limit, setLimit] = useState(10);
  const [total, setTotal] = useState(0);
  const debouncedSearch = useDebounce(search, 600);

  const resolver = yupResolver(schema) as unknown as Resolver<SequenceFormValues>;

  const {
    control,
    handleSubmit,
    reset,
    formState: { errors, isSubmitting },
  } = useForm<SequenceFormValues>({
    resolver,
    defaultValues: {
      type: "INVOICE",
      prefix: "",
      lastCount: 0,
      isActive: true,
      countFrom: "NEW",
    },
  });
  const prefixPreview = useWatch({ control, name: "prefix" });
  const countFromPreview = useWatch({ control, name: "countFrom" });
  const normalizedPreviewPrefix = prefixPreview?.trim().toUpperCase() || "INV-";
  const matchingPrefixLastCount = sequences
    .filter((sequence) => sequence.prefix === normalizedPreviewPrefix)
    .reduce((max, sequence) => Math.max(max, sequence.lastCount), 0);
  const previewCount =
    countFromPreview === "CONTINUE" && matchingPrefixLastCount > 0
      ? matchingPrefixLastCount + 1
      : 1;
  const previewReference = `${normalizedPreviewPrefix}${String(previewCount).padStart(4, "0")}`;

  const buildQuery = (search: string, page: number, limit: number, status: string) => {
    const params = new URLSearchParams();
    params.append("page", page.toString());
    params.append("limit", limit.toString());
    if (search) params.append("search", search);
    if (status) params.append("status", status);
    return params.toString();
  };

  const fetchSequences = async (
    p = page,
    l = limit,
    s = search,
    selectedStatus = status,
  ) => {
    setLoading(true);
    try {
      const res = await API_Instance.get(
        `${API_Constants.referenceSequences}?${buildQuery(s, p, l, selectedStatus)}`,
      );
      setSequences(res.data.data);
      setTotal(res.data.meta.total);
      setPage(res.data.meta.page);
      setLimit(res.data.meta.limit);
    } catch (error) {
      toast.error(getAxiosErrorMessage(error));
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    fetchSequences(page, limit, debouncedSearch, status);
  }, [page, limit, debouncedSearch, status]);

  const openModal = (sequence: IReferenceSequence | null = null) => {
    setEditingSequence(sequence);
    reset({
      type: sequence?.type || "INVOICE",
      prefix: sequence?.prefix || "",
      lastCount: sequence?.lastCount || 0,
      isActive: sequence?.isActive ?? true,
      countFrom: "NEW",
    });
    setIsModalOpen(true);
  };

  const closeModal = () => {
    setEditingSequence(null);
    setIsModalOpen(false);
    reset();
  };

  const onFormSubmit: SubmitHandler<SequenceFormValues> = async (data) => {
    try {
      if (editingSequence) {
        const { countFrom: _countFrom, ...payload } = data;
        await API_Instance.put(
          `${API_Constants.referenceSequences}/${editingSequence.id}`,
          payload,
        );
        toast.success("Reference sequence updated successfully");
      } else {
        await API_Instance.post(API_Constants.referenceSequences, {
          prefix: data.prefix,
          countFrom: data.countFrom,
        });
        toast.success("Reference sequence added successfully");
      }
      fetchSequences();
      closeModal();
    } catch (err) {
      toast.error(getAxiosErrorMessage(err));
    }
  };

  const columns: ColumnsType<IReferenceSequence> = [
    {
      title: "Type",
      dataIndex: "type",
      key: "type",
      render: (text) => (
        <span className="font-medium text-slate-700">{text}</span>
      ),
    },
    {
      title: "Prefix",
      dataIndex: "prefix",
      key: "prefix",
      render: (text) => <Tag color="blue">{text}</Tag>,
    },
    {
      title: "Last Count",
      dataIndex: "lastCount",
      key: "lastCount",
      render: (count) => (
        <span className="font-medium text-slate-700">{count}</span>
      ),
    },
    {
      title: "Status",
      dataIndex: "isActive",
      key: "isActive",
      render: (isActive: boolean) => (
        <Tag color={isActive ? "green" : "default"}>
          {isActive ? "Active" : "Inactive"}
        </Tag>
      ),
    },
    {
      title: "Started At",
      dataIndex: "createdAt",
      key: "createdAt",
      render: (createdAt) => dayjs(createdAt).format("DD-MM-YYYY hh:mm:ss A"),
    },
    {
      title: "Ended At",
      dataIndex: "endedAt",
      key: "endedAt",
      render: (endedAt) => endedAt ? dayjs(endedAt).format("DD-MM-YYYY hh:mm:ss A") : "-",
    },
    // {
    //   title: "Actions",
    //   key: "actions",
    //   width: 80,
    //   render: (_, record) => (
    //     <div className="flex space-x-2">
    //       <button
    //         onClick={() => openModal(record)}
    //         className="text-[#1677ff] hover:text-[#579af8]"
    //       >
    //         <Edit className="h-5 w-5" />
    //       </button>
    //     </div>
    //   ),
    // },
  ];

  return (
    <div className="flex flex-col gap-4 px-4 py-6">
      <div className="flex flex-col md:flex-row justify-between items-start md:items-center gap-4">
        <div>
          <h2 className="text-2xl font-bold text-slate-800 flex items-center gap-2">
            <Hash className="text-blue-600" /> Reference Sequences
          </h2>
          <p className="text-slate-500 text-sm mt-1">
            Manage invoice prefixes and counters for generated references.
          </p>
        </div>
        <Button
          type="primary"
          icon={<Plus size={16} />}
          onClick={() => openModal()}
        >
          Change Sequence
        </Button>
      </div>

      <Card className="shadow-sm border border-slate-200 rounded-xl">
        <div className="flex flex-col md:flex-row justify-between items-center gap-4 mb-4">
          <div className="flex flex-col md:flex-row gap-3 w-full">
            <Input
              placeholder="Search sequences..."
              prefix={<Search size={16} className="text-slate-400" />}
              className="w-full md:w-72"
              allowClear
              autoComplete="off"
              onChange={(e) => {
                setPage(1);
                setSearch(e.target.value);
              }}
            />
            <Select
              value={status}
              className="w-full md:w-44"
              onChange={(value) => {
                setPage(1);
                setStatus(value);
              }}
              options={[
                { label: "All Status", value: "" },
                { label: "Active", value: "active" },
                { label: "Inactive", value: "inactive" },
              ]}
            />
          </div>
          <div className="text-slate-500 text-sm whitespace-nowrap">
            Total: <span className="font-semibold text-slate-800">{total}</span>
          </div>
        </div>

        <Table
          columns={columns}
          dataSource={sequences}
          loading={loading}
          pagination={false}
          rowKey="id"
          scroll={{ x: 800 }}
          className="border border-slate-100 rounded-lg overflow-hidden"
        />

        <div className="flex justify-end mt-4">
          <Pagination
            current={page}
            total={total}
            pageSize={limit}
            onChange={(p, pageSize) => {
              setPage(p);
              setLimit(pageSize);
            }}
            showSizeChanger
            showTotal={(total) => `Total ${total} items`}
          />
        </div>
      </Card>

      <Modal
        isOpen={isModalOpen}
        onClose={closeModal}
        title={editingSequence ? "Edit Sequence" : "Add Sequence"}
      >
        <Form layout="vertical" onFinish={handleSubmit(onFormSubmit)}>
          {editingSequence ? (
            <Form.Item
              label="Type"
              validateStatus={errors.type ? "error" : ""}
              help={errors.type?.message}
              required
            >
              <Controller
                name="type"
                control={control}
                render={({ field }) => (
                  <Input {...field} placeholder="Enter type (e.g. INVOICE)" />
                )}
              />
            </Form.Item>
          ) : (
            <div className="mb-4 rounded-lg border border-blue-100 bg-blue-50 px-4 py-3">
              <div className="text-xs font-semibold uppercase tracking-wide text-blue-600">
                Sequence Type
              </div>
              <div className="mt-1 flex items-center gap-2">
                <Tag color="blue" className="m-0">
                  INVOICE
                </Tag>
                <span className="text-sm text-slate-600">
                  New sequences are created for invoice references.
                </span>
              </div>
            </div>
          )}

          <Form.Item
            label="Prefix"
            validateStatus={errors.prefix ? "error" : ""}
            help={errors.prefix?.message}
            required
          >
            <Controller
              name="prefix"
              control={control}
              render={({ field }) => (
                <Input {...field} placeholder="Enter prefix (e.g. INV-)" />
              )}
            />
          </Form.Item>

          {editingSequence ? (
            <>
              <Form.Item
                label="Last Count"
                validateStatus={errors.lastCount ? "error" : ""}
                help={errors.lastCount?.message}
                required
              >
                <Controller
                  name="lastCount"
                  control={control}
                  render={({ field }) => (
                    <InputNumber
                      min={0}
                      className="w-full"
                      value={field.value}
                      onChange={(value) => field.onChange(value ?? 0)}
                    />
                  )}
                />
              </Form.Item>

              <Form.Item label="Active">
                <Controller
                  name="isActive"
                  control={control}
                  render={({ field }) => (
                    <Switch checked={field.value} onChange={field.onChange} />
                  )}
                />
              </Form.Item>
            </>
          ) : (
            <>
              <div className="mb-4 rounded-lg border border-slate-200 bg-slate-50 px-4 py-3">
                <div className="text-xs font-semibold uppercase tracking-wide text-slate-500">
                  Preview
                </div>
                <div className="mt-1 text-xl font-bold text-slate-800">
                  {previewReference}
                </div>
              </div>

              <Form.Item
                label="Prefix Mode"
                validateStatus={errors.countFrom ? "error" : ""}
                help={errors.countFrom?.message}
                required
              >
                <Controller
                  name="countFrom"
                  control={control}
                  render={({ field }) => (
                    <Radio.Group
                      {...field}
                      className="grid grid-cols-1 gap-3 md:grid-cols-2"
                    >
                      <Radio.Button
                        value="NEW"
                        className="h-auto rounded-lg border px-4 py-3 text-left"
                      >
                        <div className="font-semibold text-slate-800">
                          New prefix
                        </div>
                        <div className="text-xs text-slate-500">
                          Use when this prefix has not been used before.
                        </div>
                      </Radio.Button>
                      <Radio.Button
                        value="CONTINUE"
                        className="h-auto rounded-lg border px-4 py-3 text-left"
                      >
                        <div className="font-semibold text-slate-800">
                          Continue prefix
                        </div>
                        <div className="text-xs text-slate-500">
                          Use only when this prefix already exists.
                        </div>
                      </Radio.Button>
                    </Radio.Group>
                  )}
                />
              </Form.Item>
            </>
          )}

          <div className="flex justify-end gap-3 mt-4">
            <Button onClick={closeModal}>Cancel</Button>
            <Button type="primary" htmlType="submit" loading={isSubmitting}>
              {editingSequence ? "Save Sequence" : "Create Sequence"}
            </Button>
          </div>
        </Form>
      </Modal>
    </div>
  );
};

export default ReferenceSequencesPage;
