"use client";
import { useCallback, useEffect, useState } from "react";
import CustomInputForm from "../CustomInputForm";
import { useRouter, useSearchParams } from "next/navigation";
import { useTranslation } from "react-i18next";
import {
  FieldErrors,
  FormProvider,
  SubmitErrorHandler,
  SubmitHandler,
  useForm,
} from "react-hook-form";
import { CreateStaffInputs, deleteStaff, saveStaff, teamHistory } from "@/app/api/staff/actions";
import { Button, Stack, Tab, Tabs, TabsProps, Typography } from "@mui/material";
// import CreateStaffForm from "../CreateStaffForm";
import { comboProp } from "@/app/api/companys/actions";
// import StaffInfo from "./StaffInfo";
import { Check, Close, ConstructionOutlined, RestartAlt } from "@mui/icons-material";
import DeleteIcon from "@mui/icons-material/Delete";
import StaffInfo from "./StaffInfo";
import { IndividualStaff, projects, SalaryEffectiveInfo } from "@/app/api/staff";
import dayjs from "dayjs";
import ProjectHistory from "./ProjectHistory";
import { InfoHistory } from "./EditStaffWrapper";
import { fetchIndivTeam } from "@/app/api/team";
import { deleteDialog, successDialog } from "../Swal/CustomAlerts";
// import { useGridApiContext } from '@mui/x-data-grid';

export interface comboItem {
  company: comboProp[];
  team: comboProp[];
  department: comboProp[];
  position: comboProp[];
  grade: comboProp[];
  skill: comboProp[];
  salary: comboProp[];
}

interface formProps {
  Staff: IndividualStaff
  combos: comboItem;
  SalaryEffectiveInfo: SalaryEffectiveInfo[];
  InvolvedProject: projects[]
  InfoHistory: InfoHistory
}


const EditStaff: React.FC<formProps> = ({ Staff, combos, SalaryEffectiveInfo, InvolvedProject, InfoHistory }) => {
  const defaultSkillset = Staff.skillset.map((s: any) => s.skill.id)
  const { t } = useTranslation();
  const searchParams = useSearchParams()
  const [tabIndex, setTabIndex] = useState(0);
  const id = parseInt(searchParams.get("id") || "0");
  const formProps = useForm<CreateStaffInputs
   & { salaryEffectiveInfo: SalaryEffectiveInfo[] }
   & { delSalaryEffectiveInfo: number[] }>({
    defaultValues: {
      staffId: Staff.staffId,
      name: Staff.name,
      companyId: Staff.company.id,
      teamId: Staff.team?.id,
      departmentId: Staff.department?.id,
      gradeId: Staff.grade?.id,
      skillSetId: defaultSkillset,
      // removeSkillSetId: [],
      currentPositionId: Staff.currentPosition?.id,
      salaryId: Staff.salary.salaryPoint,
      employType: Staff.employType,
      email: Staff.email,
      phone1: Staff.phone1,
      phone2: Staff.phone2,
      emergContactName: Staff.emergContactName,
      emergContactPhone: Staff.emergContactPhone,
      joinDate: Staff.joinDate ? dayjs(Staff.joinDate as string).format("YYYY-MM-DD") : null,
      joinPositionId: Staff.joinPosition?.id || null,
      departDate: Staff.departDate ? dayjs(Staff.departDate as string).format("YYYY-MM-DD") : null,
      departReason: Staff.departReason,
      remark: Staff.remark,
      salaryEffectiveInfo: SalaryEffectiveInfo.map(item => {
        return ({
        id: item.id,
        salaryPoint: combos.salary.filter(sal => sal.id === item.salaryPoint)[0].label,
        date: dayjs(item.date).toDate(),
      })}),
      delSalaryEffectiveInfo: [],
      teamHistory: InfoHistory.teamLog ? InfoHistory.teamLog.map(item => {
        return ({
          id: item.id,
          team: item.team.name,
          from: dayjs(item.from.join()).toDate(),
          to: item.to ? dayjs(item.to.join()).toDate() : undefined,
        })
      }) : [],
      delTeamHistory: [],
      gradeHistory: InfoHistory.gradeLog ? InfoHistory.gradeLog.map(item => {
        return ({
          id: item.id,
          grade: item.grade.name,
          from: dayjs(item.from.join()).toDate(),
          to: item.to ? dayjs(item.to.join()).toDate() : undefined,
        })
      }) : [],
      delGradeHistory: [],
      positionHistory: InfoHistory.positionLog ? InfoHistory.positionLog.map(item => {
        return ({
          id: item.id,
          position: item.position.name,
          from: dayjs(item.from.join()).toDate(),
          to: item.to ? dayjs(item.to.join()).toDate() : undefined,
        })
      }) : [],
      delPositionHistory: [],
  }});

  const [serverError, setServerError] = useState("");
  const router = useRouter();
  
  const errors = formProps.formState.errors;

  const onSubmit = useCallback<SubmitHandler<CreateStaffInputs & { salaryEffectiveInfo: SalaryEffectiveInfo[] } >>(
    async (data) => {
      try {
        // console.log(data);
        let haveError = false;
        const regex_email = /^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/
        const regex_phone = /^\d{8}$/

        if (!regex_email.test(data.email)) {
          haveError = true
          formProps.setError("email", { message: t("Please Enter Correct Email."), type: "required" })
        }
        if (!regex_phone.test(data.phone1)) {
          haveError = true
          formProps.setError("phone1", { message: t("Please Enter Correct Phone No.."), type: "required" })
        }
        if (data.emergContactPhone && !regex_phone.test(data.emergContactPhone)) {
          haveError = true
          formProps.setError("emergContactPhone", { message: t("Please Enter Correct Phone No.."), type: "required" })
        }
        if (data.phone2 && data.phone2?.length > 0) {
          if(!regex_phone.test(data.phone2)) {
            haveError = true
            formProps.setError("phone2", { message: t("Please Enter Correct Phone No.."), type: "required" })
          }
        }
        if (data.phone1 === data.phone2 || data.phone1 === data.emergContactPhone || data.phone2 && data.phone2 === data.emergContactPhone && data.phone2.length > 0) {
          haveError = true
          formProps.setError("phone1", { message: t("Please Enter Different Phone No.."), type: "required" })
          if (data.phone2!.length > 0) {
            formProps.setError("phone2", { message: t("Please Enter Different Phone No.."), type: "required" })
          }
          formProps.setError("emergContactPhone", { message: t("Please Enter Different Phone No.."), type: "required" })
        }
        if (!regex_email.test(data.email)) {
          haveError = true
          formProps.setError("email", { message: t("Please Enter Correct Email."), type: "required" })
        }
        if (!data.companyId) {
          haveError = true
          formProps.setError("companyId", { message: t("Please Enter Company."), type: "required" })
        }
        if (!data.employType) {
          haveError = true
          formProps.setError("employType", { message: t("Please Enter Employ Type."), type: "required" })
        }
        if (!data.salaryId) {
          haveError = true
          formProps.setError("salaryId", { message: t("Please Enter Salary."), type: "required" })
        }
        // if (data.joinDate && data.departDate && new Date(data.departDate) <= new Date(data.joinDate)) {
        //   haveError = true
        //   formProps.setError("departDate", { message: t("Depart Date cannot be earlier than Join Date."), type: "required" })
        // }
        if (haveError) {
          return
        }
        
        const teamHistory = data.teamHistory.map((item) => ({
          id: item.id,
          team: combos.team.filter(team => team.label === item.team)[0].id,
          from: dayjs(item.from).format('YYYY-MM-DD'),
          // to: item.to != undefined ? dayjs(item.to).format('YYYY-MM-DD') : undefined,
        }))
        .sort((a, b) => new Date(a.from).getTime() - new Date(b.from).getTime())

        const gradeHistory = data.gradeHistory.map((item) => ({
          id: item.id,
          grade: combos.grade.filter(grade => grade.label === item.grade)[0].id,
          from: dayjs(item.from).format('YYYY-MM-DD'),
          // to: item.to != undefined ? dayjs(item.to).format('YYYY-MM-DD') : undefined,
        }))
        .sort((a, b) => new Date(a.from).getTime() - new Date(b.from).getTime())

        const positionHistory = data.positionHistory.map((item) => ({
          id: item.id,
          position: combos.position.filter(position => position.label === item.position)[0].id,
          from: dayjs(item.from).format('YYYY-MM-DD'),
          // to: item.to != undefined ? dayjs(item.to).format('YYYY-MM-DD') : undefined,
        }))
        .sort((a, b) => new Date(a.from).getTime() - new Date(b.from).getTime())

        const salaryEffectiveInfo = data.salaryEffectiveInfo.map((item: SalaryEffectiveInfo) => ({
          id: item.id,
          salaryPoint: chopSalaryPoints(item.salaryPoint),
          date: dayjs(item.date).format('YYYY-MM-DD').toString()
        }))

        const postData: CreateStaffInputs = {
          id: id,
          ...data,
          salaryEffectiveInfo: salaryEffectiveInfo,
          teamHistory: teamHistory ?? [],
          gradeHistory: gradeHistory ?? [],
          positionHistory: positionHistory ?? [],
          delTeamHistory: data.delTeamHistory ? data.delTeamHistory : [],
          delGradeHistory: data.delGradeHistory ? data.delGradeHistory : [],
          delPositionHistory: data.delPositionHistory ? data.delPositionHistory : [],
        }
        if (postData.joinDate) {
          postData.joinDate = dayjs(postData.joinDate).format("YYYY-MM-DD")
        }
        if (postData.departDate) {
          postData.departDate = dayjs(postData.departDate).format("YYYY-MM-DD")
        }
        console.log(postData)
        await saveStaff(postData)
        router.replace("/settings/staff")
      } catch (e: any) {
        console.log(e);
        formProps.setError("staffId", { message: t("Please Enter Employ Type."), type: "required" })
        let msg = ""
        if (e.message === "Duplicated StaffId Found") {
          msg = t("Duplicated StaffId Found")
        }
        setServerError(`${t("An error has occurred. Please try again later.")} ${msg} `);
      }
    },
    [router]
  );
  
  const handleCancel = () => {
    router.back();
  };

  function chopSalaryPoints(input: string | number): number | null {
    if (typeof input === 'string') {
      const match = input.match(/(\d+) \((\d+) - (\d+)\)/);
      if (match) {
        return parseInt(match[1], 10);
      }
    } else if (typeof input === 'number') {
      return input;
    }
    return null;
  }

  const handleTabChange = useCallback<NonNullable<TabsProps["onChange"]>>(
    (_e, newValue) => {
      setTabIndex(newValue);
    },
    []
  );

  const handleDelete = useCallback(() => {
    console.log(id)
    deleteDialog(async () => {
      await deleteStaff(id);
      router.replace("/settings/staff")
      successDialog(t("Delete Success"), t);
    }, t);
  }, [])

  return (
    <>
      <FormProvider {...formProps}>
      <Stack
          spacing={2}
          component="form"
          onSubmit={formProps.handleSubmit(onSubmit)}
        >
          {serverError && (
            <Typography variant="body2" color="error" alignSelf="flex-end">
              {serverError}
            </Typography>
          )}
          <Stack
            direction="row"
            justifyContent="space-between"
            flexWrap="wrap"
            rowGap={2}
          >
            <Tabs
              value={tabIndex}
              onChange={handleTabChange}
              variant="scrollable"
            >
              <Tab label={t("Info")}/>
              <Tab label={t("Involved Project History")} />
            </Tabs>
          </Stack>
          {tabIndex == 0 && Staff && <StaffInfo combos={combos} />}
          {tabIndex == 1 && <ProjectHistory InvolvedProject={InvolvedProject}/>}
          {tabIndex == 0 &&
          <Stack direction="row" justifyContent="flex-end" gap={1}>
          <Button
              variant="contained"
              color="error"
              startIcon={<DeleteIcon />}
              onClick={() => handleDelete()}
            >
              {t("Delete")}
            </Button>
          <Button
              variant="text"
              startIcon={<RestartAlt />}
              onClick={()=> window.location.reload()}
            >
              {t("Reset")}
            </Button>
            <Button
              variant="outlined"
              startIcon={<Close />}
              onClick={handleCancel}
            >
              {t("Cancel")}
            </Button>
            <Button
              variant="contained"
              startIcon={<Check />}
              type="submit"
              // disabled={Boolean(formProps.watch("isGridEditing"))}
            >
              {t("Confirm")}
            </Button>
          </Stack>
          }
        </Stack>
      </FormProvider>
    </>
  );
};

export default EditStaff;