"use client"

import React, { useEffect } from "react"
import { Button, DatePicker, Form, Input, Select, Switch, TimePicker } from "antd"
import { useState } from "react"
import { useTranslations } from "next-intl"
import { filterOption } from "@/util/Common"
import dayjs, { Dayjs } from "dayjs"
import { useRouter } from "@/i18n/routing"
import { useCreateEvent, useGetEventTypes, useUpdateEvent } from "@/hook/useCalendar"
import { useNotificationContext } from "../Layout/NotificationContext"

type IProps = {
  submit: boolean
  cancel: boolean
  onError: () => void
  event?: any
}

export default function FormAddEvent({ submit, cancel, onError, event }: IProps) {
  const [formRef] = Form.useForm()
  const router = useRouter()
  const [loading, setLoading] = useState(false)
  const trans = useTranslations("calendar")
  const tranButton = useTranslations("button")
  const transGeneral = useTranslations("general")
  const tranForm = useTranslations("form")
  const transRq = useTranslations("required")
  const { data: dataType } = useGetEventTypes()
  const createEvent = useCreateEvent()
  const updateEvent = useUpdateEvent()
  const { notify } = useNotificationContext()
  const transMessage = useTranslations("message")

  useEffect(() => {
    formRef.resetFields()
    setLoading(false)
  }, [])

  useEffect(() => {
    if (event) {
      formRef.setFieldsValue({
        type: event.type,
        title: event.title,
        description: event.description,
        date: event.date ? dayjs.unix(event.date) : null,
        todate: event.todate ? dayjs.unix(event.todate) : null,
        time_from: event.time_from ? dayjs(event.time_from, "hh:mm A") : null,
        time_to: event.time_to ? dayjs(event.time_to, "hh:mm A") : null,
        allday: event.allday,
        location: event.location,
      })
    } 
  }, [event])

  const onFinish = (values: any) => {
    setLoading(true)
    if (event) {
      updateEvent
        .mutateAsync({
          id: event.id,
          type: values.type,
          title: values.title,
          description: values.description,
          date: values.date ? values.date.valueOf() / 1000 : undefined,
          todate: values.todate ? values.todate.valueOf() / 1000 : undefined,
          time_from: values.time_from ? values.time_from.format("hh:mm A") : null,
          time_to: values.time_to ? values.time_to.format("hh:mm A") : null,
          allday: values.allday,
          location: values.location,
        })
        .then(() => {
          notify({
            type: "success",
            message: transMessage("success"),
            description: trans("event_updated_successfully"),
          })
          router.push("/calendar")
        })
        .catch((error) => {
          onError()
          const concatenatedMsgs = error?.response?.data.msgs || transMessage("fail")
          notify({
            type: "error",
            message: transMessage("something_wrong"),
            description: concatenatedMsgs,
          })
        })
        .finally(() => {
          setLoading(false)
        })
    } else {
      createEvent
        .mutateAsync({
          type: values.type,
          title: values.title,
          description: values.description,
          date: values.date ? values.date.valueOf() / 1000 : undefined,
          todate: values.todate ? values.todate.valueOf() / 1000 : undefined,
          time_from: values.time_from ? values.time_from.format("hh:mm A") : null,
          time_to: values.time_to ? values.time_to.format("hh:mm A") : null,
          allday: values.allday,
          location: values.location,
        })
        .then(() => {
          notify({
            type: "success",
            message: transMessage("success"),
            description: trans("event_created_successfully"),
          })
          router.push("/calendar")
        })
        .catch((error) => {
          onError()
          const concatenatedMsgs = error?.response?.data.msgs || transMessage("fail")
          notify({
            type: "error",
            message: transMessage("something_wrong"),
            description: concatenatedMsgs,
          })
        })
        .finally(() => {
          setLoading(false)
        })
    }
  }

  useEffect(() => {
    if (cancel) {
      formRef.resetFields()
      router.push("/calendar")
    } else if (submit) {
      formRef.submit()
    }
  }, [submit, cancel])

  const handleCancel = () => {
    formRef.resetFields()
    router.push("/calendar")
  }

  const disabledEndDate = (endDay: Dayjs | null) => {
    const startDay = formRef.getFieldValue("date")
    return startDay && endDay ? endDay.isBefore(startDay, "day") : false
  }

  const disabledStartDate = (startDay: Dayjs | null) => {
    const toDate = formRef.getFieldValue("todate")
    return toDate && startDay ? startDay.isAfter(toDate, "day") : false
  }

  return (
    <div className="px-4 py-6 grow overflow-y-auto">
      <Form
        name="add_event"
        form={formRef}
        onFinish={onFinish}
        onError={() => onError()}
        autoComplete="off"
        initialValues={!event ? { allday: false } : {}}
        layout="vertical">
        <div className="grid gap-4 grid-cols-12 lg:grid-rows-3">
          <div className="col-span-12 lg:col-span-8 bg-[var(--secondary-10)] rounded-lg border border-solid border-[var(--secondary-20)] px-4 lg:px-6 pt-6 lg:row-span-3">
            <p className="text-base font-semibold mb-6">{trans("event_information")}</p>
            <Form.Item
              label={transGeneral("type")}
              name="type"
              rules={[{ required: true, message: transRq("cannot_empty") }]}>
              <Select
                showSearch
                size="large"
                placeholder="Choose type"
                filterOption={filterOption}
                options={
                  dataType?.data
                    ? dataType?.data.map((item) => {
                        return {
                          label: item.name,
                          value: item.id,
                        }
                      })
                    : []
                }
              />
            </Form.Item>
            <Form.Item
              label={tranForm("title")}
              name="title"
              rules={[
                { required: true, message: transRq("cannot_empty") },
                { max: 1024 },
              ]}>
              <Input
                placeholder="Input Event title"
                size="large"
                onBlur={(e) => {
                  formRef.setFieldsValue({
                    title: e.target.value.trim(),
                  })
                }}
              />
            </Form.Item>
            <Form.Item
              label="Location"
              name="location"
              rules={[
                { required: true, message: transRq("cannot_empty") },
                { max: 1024 },
              ]}>
              <Input
                placeholder="Input Event Location"
                size="large"
                onBlur={(e) => {
                  formRef.setFieldsValue({
                    location: e.target.value.trim(),
                  })
                }}
              />
            </Form.Item>
            <Form.Item
              label={tranForm("description")}
              name="description"
              rules={[
                { required: true, message: tranForm("placeholder_input", { name: tranForm("description") }) },
                { max: 4096 },
              ]}>
              <Input.TextArea
                placeholder={tranForm("placeholder_input", { name: tranForm("description") })}
                rows={5}
                maxLength={6}
                onBlur={(e) => {
                  formRef.setFieldsValue({
                    description: e.target.value.trim(),
                  })
                }}
              />
            </Form.Item>
          </div>
          <div className="col-span-12 lg:col-span-4 bg-[var(--secondary-10)] rounded-lg border border-solid border-[var(--secondary-20)] px-4 lg:px-6 pt-6">
            <p className="text-base font-semibold mb-6">{trans("all_days")}</p>
            <div className="flex items-start justify-start">
              <Form.Item
                label=""
                name="allday"
                valuePropName="checked">
                <Switch />
              </Form.Item>
              <Form.Item
                noStyle
                shouldUpdate={(prev, curr) => prev.allday !== curr.allday}>
                {() => {
                  const value = formRef.getFieldValue("allday")
                  return <span className="ml-2 text-sm text-gray-600 mt-1.5">{value ? "Enable" : transGeneral("disabled")}</span>
                }}
              </Form.Item>
            </div>
          </div>
          <div className="col-span-12 lg:col-span-4 bg-[var(--secondary-10)] rounded-lg border border-solid border-[var(--secondary-20)] px-4 lg:px-6 pt-6">
            <p className="text-base font-semibold mb-6">
              <span className="text-[var(--danger-50)]">*</span> {transGeneral("start")}
            </p>
            <div className="gap-2 grid grid-cols-12">
              <Form.Item
                className="col-span-6 md:col-span-5"
                label=""
                name="time_from"
                dependencies={["date", "time_to", "todate"]}
                rules={[{ required: true, message: transRq("cannot_empty") }]}>
                <TimePicker
                  className="w-full"
                  format="HH:mm"
                  size="large"
                  disabledTime={() => {
                    const timeTo = formRef.getFieldValue("time_to")
                    const startDay = formRef.getFieldValue("date")
                    const toDate = formRef.getFieldValue("todate")
                    if (!timeTo || !startDay || !toDate) return {}
                    if (startDay.isSame(toDate, "day")) {
                      const endHour = timeTo.hour()
                      const endMinute = timeTo.minute()

                      return {
                        disabledHours: () => Array.from({ length: 24 }, (_, h) => (h > endHour ? h : null)).filter((h) => h !== null),
                        disabledMinutes: (selectedHour: number) =>
                          selectedHour === endHour ? Array.from({ length: 60 }, (_, m) => (m > endMinute ? m : null)).filter((m) => m !== null) : [],
                      }
                    }
                    return {}
                  }}
                />
              </Form.Item>
              <Form.Item
                className="col-span-6 md:col-span-7"
                label=""
                name="date"
                dependencies={["time_from", "time_to", "todate"]}
                rules={[{ required: true, message: transRq("cannot_empty") }]}>
                <DatePicker
                  className="w-full"
                  format="MMM DD, YYYY"
                  size="large"
                  disabledDate={disabledStartDate}
                />
              </Form.Item>
            </div>
          </div>
          <div className="col-span-12 lg:col-span-4 bg-[var(--secondary-10)] rounded-lg border border-solid border-[var(--secondary-20)] px-4 lg:px-6 pt-6">
            <p className="text-base font-semibold mb-6">
              <span className="text-[var(--danger-50)]">*</span> {transGeneral("end")}
            </p>
            <div className="gap-2 grid grid-cols-12">
              <Form.Item
                className="col-span-6 md:col-span-5"
                label=""
                name="time_to"
                dependencies={["time_from", "date", "todate"]}
                rules={[{ required: true, message: transRq("cannot_empty") }]}>
                <TimePicker
                  className="w-full"
                  format="HH:mm"
                  size="large"
                  disabledTime={() => {
                    const timeFrom = formRef.getFieldValue("time_from")
                    const startDay = formRef.getFieldValue("date")
                    const toDate = formRef.getFieldValue("todate")
                    if (!timeFrom || !startDay || !toDate) return {}
                    if (startDay.isSame(toDate, "day")) {
                      const startHour = timeFrom.hour()
                      const startMinute = timeFrom.minute()

                      return {
                        disabledHours: () => Array.from({ length: 24 }, (_, h) => (h < startHour ? h : null)).filter((h) => h !== null),
                        disabledMinutes: (selectedHour: number) =>
                          selectedHour === startHour ? Array.from({ length: 60 }, (_, m) => (m < startMinute ? m : null)).filter((m) => m !== null) : [],
                      }
                    }
                    return {}
                  }}
                />
              </Form.Item>
              <Form.Item
                className="col-span-6 md:col-span-7"
                label=""
                name="todate"
                dependencies={["time_from", "date", "time_to"]}
                rules={[{ required: true, message: transRq("cannot_empty") }]}>
                <DatePicker
                  className="w-full"
                  format="MMM DD, YYYY"
                  size="large"
                  disabledDate={disabledEndDate}
                />
              </Form.Item>
            </div>
          </div>
        </div>
        <div className="pt-4 flex items-center gap-2 md:hidden">
          <Button
            className="w-full md:!text-base lg:!text-lg font-bold !h-10 md:!h-12 xl:!h-16 !rounded-lg !border-[var(--secondary-20)] !bg-[var(--secondary-10)]"
            loading={loading}
            onClick={handleCancel}>
            {tranButton("cancel")}
          </Button>
          <Button
            type="primary"
            htmlType="submit"
            className="w-full md:!text-base lg:!text-lg font-bold !h-10 md:!h-12 xl:!h-16 !rounded-lg"
            loading={loading}>
            {tranButton("submit")}
          </Button>
        </div>
      </Form>
    </div>
  )
}