import { useForm, useWatch } from "react-hook-form";
import { motion } from "framer-motion";
import {
  Calendar,
  Target,
  Users,
  FileText,
  Plus,
  ArrowLeft,
  User,
} from "lucide-react";
import { useNavigate, useParams, useSearchParams } from "react-router-dom";
import { useEffect, useMemo } from "react";
import { toast } from "sonner";
import { useTranslation } from "react-i18next";
import { useLocalizedName } from "@/shared/common/localizedName";
import { useAuth } from "@/shared/context/AuthContext";
import { useUnitContext } from "@/shared/context/UnitContext";
import { Button } from "@/shared/common/ui/button";
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "@/shared/common/ui/card";
import { Alert, AlertDescription, AlertTitle } from "@/shared/common/ui/alert";
import { Info } from "lucide-react";
import { GenericForm } from "@/performance-management/utils/generic-form";
import { TimeFrame } from "@/performance-management/utils/shared-field-types";
import {
  useEmployeePlanMutations,
  useEmployeePositions,
  usePositionsByUnit,
  useEmployeePlan,
  useServices,
  useEmployeePlanByPlanId,
} from "@/performance-management/hooks/useEmployeePlan";
import { FormField } from "@/performance-management/utils/shared-field-types";
import { useMinePlan } from "@/performance-management/hooks/usePlans";

// Define PlanType enum for employee plans
export enum EmployeePlanType {
  NUMBER = "number",
  PERCENTAGE = "percent",
  BOOLEAN = "boolean",
}

export interface EmployeePlanFormValues {
  parentEmployeePlanId?: string;
  employeePositionId: string;
  planId: string;
  serviceId: string;
  planType: EmployeePlanType;
  expectedQuantity: number;
  week: string | number;
  month: string | number;
  quarter: string | number;
  timeframe: string;
}

interface EmployeePlanFormProps {
  parentEmployeePlanId?: string;
  onSuccess?: () => void;
}

export default function EmployeePlanForm({
  parentEmployeePlanId: propParentId,
  onSuccess,
}: EmployeePlanFormProps = {}) {
  const navigate = useNavigate();
  const { t } = useTranslation();

  const {
    id,
    employeePositionId: pathEmployeePositionId,
    planId: pathPlanId,
    serviceId: pathServiceId,
  } = useParams<{
    id: string;
    employeePositionId?: string;
    planId?: string;
    serviceId?: string;
  }>();

  const [searchParams] = useSearchParams();
  const urlParentId = searchParams.get("parentEmployeePlanId");
  const urlEmployeePositionId = searchParams.get("employeePositionId");
  const urlPlanId = searchParams.get("planId");
  const urlServiceId = searchParams.get("serviceId");

  const parentId = propParentId || urlParentId;
  const employeePositionId = urlEmployeePositionId || pathEmployeePositionId;
  const planId = urlPlanId || pathPlanId;
  const serviceId = urlServiceId || pathServiceId;

  const { user, selectedPositionId } = useAuth();
  const localizedName = useLocalizedName();
  const isEdit = !!id;

  // Pick the employee record matching the globally-selected position, so a
  // user with positions in multiple orgs uses the right org. Falls back to
  // the first employee record when nothing is selected.
  const organizationId = useMemo(() => {
    const employees = user?.employee ?? [];
    if (selectedPositionId) {
      const match = employees.find((emp) =>
        emp.positions?.some(
          (p) =>
            p.employeePositionId === selectedPositionId ||
            p.id === selectedPositionId,
        ),
      );
      if (match?.organizationId) return match.organizationId;
    }
    return employees[0]?.organizationId;
  }, [user, selectedPositionId]);

  const unitContext = useUnitContext();
  const unitsQuery = unitContext?.getList(organizationId!, {
    take: 300,
    skip: 0,
  });
  const unitId = unitsQuery?.data?.data?.items?.[0]?.id ?? "";

  const { data: positionsData } = usePositionsByUnit(unitId);
  const { data: employeePlanDetail } = useEmployeePlan(id || "");
  const { create: createMutation, update: updateMutation } =
    useEmployeePlanMutations();
  const { data: myPlans } = useMinePlan();
  console.log("my plans ", myPlans);
  //
  const { data: employeePositionsData } = useEmployeePositions();
  console.log("employee positoin ", employeePositionsData);

  // Fetch services and parent employee plan details
  const { data: servicesData } = useServices();
  console.log("services ", servicesData);

  // Fetch parent employee plan detail if parentId is present in URL
  const { data: urlParentEmployeePlanDetail } = useEmployeePlan(parentId || "");

  const normalizeTimeframe = (val: unknown): string => {
    if (!val) return TimeFrame.YEAR;
    const str = String(val).toLowerCase();
    if (str.includes("year")) return TimeFrame.YEAR;
    if (str.includes("quarter")) return TimeFrame.QUARTER;
    if (str.includes("month")) return TimeFrame.MONTH;
    if (str.includes("week")) return TimeFrame.WEEK;
    if (str.includes("day")) return TimeFrame.DAY;
    return TimeFrame.YEAR;
  };

  const initialEmployeePlanFormValues = useMemo(
    () => ({
      parentEmployeePlanId:
        employeePlanDetail?.data?.parentEmployeePlanId || parentId || undefined,
      employeePositionId:
        employeePlanDetail?.data?.employeePositionId ||
        employeePositionId ||
        "",
      planId: employeePlanDetail?.data?.planId || planId || "",
      serviceId: employeePlanDetail?.data?.serviceId || serviceId || "",
      planType: employeePlanDetail?.data?.planType || EmployeePlanType.NUMBER,
      expectedQuantity: employeePlanDetail?.data?.expectedQuantity || 0,
      week: employeePlanDetail?.data?.week?.toString() || "0",
      month: employeePlanDetail?.data?.month?.toString() || "0",
      quarter: employeePlanDetail?.data?.quarter?.toString() || "0",
      timeframe: (() => {
        const rawTimeframe = employeePlanDetail?.data?.timeframe;
        if (rawTimeframe) return normalizeTimeframe(rawTimeframe);

        // Fallback for sub-plan creation when parent data is missing but parentId is present
        const parent = urlParentEmployeePlanDetail?.data;
        if (!parentId || !parent) {
          return parentId ? TimeFrame.QUARTER : TimeFrame.YEAR;
        }

        const pt = normalizeTimeframe(parent.timeframe);
        if (pt === TimeFrame.YEAR) return TimeFrame.QUARTER;
        if (pt === TimeFrame.QUARTER) return TimeFrame.QUARTER;
        if (pt === TimeFrame.MONTH) return TimeFrame.WEEK;
        if (pt === TimeFrame.WEEK) return TimeFrame.DAY;
        return TimeFrame.YEAR;
      })(),
    }),
    [
      employeePlanDetail?.data,
      parentId,
      employeePositionId,
      planId,
      serviceId,
      urlParentEmployeePlanDetail?.data,
    ]
  );

  const form = useForm<EmployeePlanFormValues>({
    defaultValues: initialEmployeePlanFormValues,
    values: isEdit || !!parentId ? initialEmployeePlanFormValues : undefined,
  });

  const watchedPlanId = useWatch({
    control: form.control,
    name: "planId",
  });
  const { data: parentEmployeePlanDetail } = useEmployeePlanByPlanId(
    watchedPlanId || ""
  );

  const positionOptions =
    positionsData?.data?.items?.map(
      (position: { id: string; title: string }) => ({
        value: position.id,
        label: position.title,
        icon: User,
      })
    ) || [];

  const employeePositionOptions =
    employeePositionsData?.items?.flatMap((emp) =>
      emp.employeePositions.map((empPos) => ({
        value: empPos.id, // employeePositionId
        label: `${emp.name.en} – ${empPos.position?.name?.am}`,
        icon: User,
      }))
    ) || [];

  // Mock data - replace with your actual data fetching
  const planOptions =
    myPlans?.data?.items?.map(
      (plan: { id: string; name: { am: string; en: string } }) => ({
        value: plan.id,
        label: localizedName(plan.name),
        icon: FileText,
      })
    ) || [];

  const serviceOptions =
    servicesData?.data?.items?.map(
      (service: { id: string; name: { am: string; en: string } }) => ({
        value: service.id,
        label: localizedName(service.name),
        icon: Users,
      })
    ) || [];

  // Determine allowed timeframe options based on parent employee plan
  const timeframeOptions = useMemo(() => {
    // Current parent detail either from URL (parentId) or watched result
    const parent =
      urlParentEmployeePlanDetail?.data || parentEmployeePlanDetail?.data;

    if (!parentId && !parent) {
      return [
        {
          value: TimeFrame.YEAR,
          label: t("employeePlans.yearly", "Yearly"),
        },
      ];
    }

    const parentTimeframe = normalizeTimeframe(parent?.timeframe);

    switch (parentTimeframe) {
      case TimeFrame.YEAR:
        return [
          {
            value: TimeFrame.YEAR,
            label: t("employeePlans.yearly", "Yearly"),
          },
          {
            value: TimeFrame.QUARTER,
            label: t("employeePlans.quarterly", "Quarterly"),
          },
        ];

      case TimeFrame.QUARTER:
        return [
          {
            value: TimeFrame.QUARTER,
            label: t("employeePlans.quarterly", "Quarterly"),
          },
        ];

      case TimeFrame.MONTH:
        return [
          {
            value: TimeFrame.WEEK,
            label: t("employeePlans.weekly", "Weekly"),
          },
        ];

      case TimeFrame.WEEK:
        return [
          {
            value: TimeFrame.DAY,
            label: t("employeePlans.daily", "Daily"),
          },
        ];

      default:
        return [
          {
            value: TimeFrame.YEAR,
            label: t("employeePlans.yearly", "Yearly"),
          },
        ];
    }
  }, [
    parentId,
    parentEmployeePlanDetail?.data,
    urlParentEmployeePlanDetail?.data,
    t,
  ]);

  // Auto-select timeframe if there's only one option
  useEffect(() => {
    if (timeframeOptions.length === 1) {
      const currentVal = form.getValues("timeframe");
      if (currentVal !== timeframeOptions[0].value) {
        form.setValue("timeframe", timeframeOptions[0].value as string, {
          shouldValidate: true,
          shouldDirty: true,
        });
      }
    }
  }, [timeframeOptions, form]);

  useEffect(() => {
    const current = form.getValues("timeframe");

    const isValid = timeframeOptions.some((opt) => opt.value === current);

    if (!isValid && timeframeOptions.length > 0) {
      form.setValue("timeframe", timeframeOptions[0].value, {
        shouldValidate: true,
        shouldDirty: true,
      });
    }
  }, [timeframeOptions, form]);

  const planTypeOptions = Object.values(EmployeePlanType).map((type) => ({
    value: type,
    label: type.charAt(0).toUpperCase() + type.slice(1).toLowerCase(),
  }));

  // TODO: Fetch employee plans for parent selection
  const employeePlanOptions =
    parentEmployeePlanDetail?.data.items?.map(
      (plan: { id: string; name: { am: string; en: string } }) => ({
        value: plan.id,
        label: localizedName(plan.name),
        icon: FileText,
      })
    ) || [];

  const watchedTimeframe = useWatch({
    control: form.control,
    name: "timeframe",
  });

  // Reset hidden fields when timeframe changes
  useEffect(() => {
    if (watchedTimeframe === TimeFrame.YEAR) {
      form.setValue("quarter", "0");
      form.setValue("month", "0");
      form.setValue("week", "0");
    } else if (watchedTimeframe === TimeFrame.QUARTER) {
      form.setValue("month", "0");
      form.setValue("week", "0");
    } else if (watchedTimeframe === TimeFrame.MONTH) {
      form.setValue("week", "0");
    }
    // For WEEK and DAY, no reset needed as they inherit from parent timeframes
  }, [watchedTimeframe, form]);

  // Inherit context from parent employee plan
  useEffect(() => {
    if (parentId && parentEmployeePlanDetail?.data && !isEdit) {
      const parent = parentEmployeePlanDetail.data;

      // Inherit timeframe context
      switch (parent.timeframe) {
        case TimeFrame.YEAR:
          form.setValue("timeframe", TimeFrame.QUARTER);
          break;
        case TimeFrame.QUARTER:
          form.setValue("timeframe", TimeFrame.QUARTER);
          if (parent.quarter)
            form.setValue("quarter", parent.quarter.toString());
          break;
        case TimeFrame.MONTH:
          form.setValue("timeframe", TimeFrame.WEEK);
          if (parent.quarter)
            form.setValue("quarter", parent.quarter.toString());
          if (parent.month) form.setValue("month", parent.month.toString());
          break;
        case TimeFrame.WEEK:
          form.setValue("timeframe", TimeFrame.DAY);
          if (parent.quarter)
            form.setValue("quarter", parent.quarter.toString());
          if (parent.month) form.setValue("month", parent.month.toString());
          if (parent.week) form.setValue("week", parent.week.toString());
          break;
        default:
          break;
      }
    }
  }, [parentId, parentEmployeePlanDetail, isEdit, form]);

  const handleSubmit = (values: EmployeePlanFormValues) => {
    // Prepare timeframe-specific fields based on selected timeframe
    const getTimeframeFields = (): {
      quarter: number;
      month: number;
      week: number;
    } => {
      const fields = {
        quarter: 0,
        month: 0,
        week: 0,
      };

      switch (values.timeframe) {
        case TimeFrame.QUARTER:
          fields.quarter = Number(values.quarter);
          break;
        case TimeFrame.MONTH:
          fields.quarter = Number(values.quarter);
          fields.month = Number(values.month);
          break;
        case TimeFrame.WEEK:
          fields.quarter = Number(values.quarter);
          fields.month = Number(values.month);
          fields.week = Number(values.week);
          break;
        case TimeFrame.DAY:
          fields.quarter = Number(values.quarter);
          fields.month = Number(values.month);
          fields.week = Number(values.week);
          break;
        // For YEAR, all fields remain 0
      }

      return fields;
    };

    const dto = {
      id: isEdit ? id : undefined,
      parentEmployeePlanId: values.parentEmployeePlanId,
      employeePositionId: values.employeePositionId,
      planId: values.planId,
      serviceId: values.serviceId,
      planType: values.planType,
      expectedQuantity: Number(values.expectedQuantity),
      timeframe: values.timeframe,
      ...getTimeframeFields(),
    };

    const mutation = isEdit ? updateMutation : createMutation;

    mutation.mutate(dto, {
      onSuccess: () => {
        toast.success(
          isEdit
            ? t(
                "employeePlans.planUpdatedSuccess",
                "Employee plan updated successfully!"
              )
            : t(
                "employeePlans.planCreatedSuccess",
                "Employee plan created successfully!"
              ),
          {
            description: `${t("employeePlans.plan", "Employee plan")} ${
              isEdit
                ? t("common.updated", "updated")
                : t("common.created", "created")
            }.`,
          }
        );
        onSuccess?.();
        if (!isEdit) {
          navigate(-1);
        }
      },
      onError: (error: { message?: string }) => {
        toast.error(
          isEdit
            ? t(
                "employeePlans.planUpdateFailed",
                "Failed to update employee plan"
              )
            : t(
                "employeePlans.planCreateFailed",
                "Failed to create employee plan"
              ),
          {
            description:
              error?.message ||
              t("common.checkInput", "Please check your input and try again."),
          }
        );
      },
    });
  };

  // Define form fields
  const employeePlanFormFields: FormField<EmployeePlanFormValues>[] = [
    // Basic Assignment Section
    {
      name: "employeePositionId",
      label: t("employeePlans.employeePosition", "Employee Position"),
      type: "select",
      options:
        employeePositionOptions.length > 0
          ? employeePositionOptions
          : positionOptions,
      required: true,
      icon: User,
      section: t("employeePlans.assignment", "Assignment"),
      colSpan: 6,
    },
    {
      name: "serviceId",
      label: t("employeePlans.service", "Service"),
      type: "select",
      options: serviceOptions,
      required: true,
      icon: Users,
      section: t("employeePlans.assignment", "Assignment"),
      colSpan: 6,
    },
    {
      name: "planId",
      label: t("employeePlans.plan", "Plan"),
      type: "select",
      options: planOptions,
      required: true,
      icon: FileText,
      section: t("employeePlans.assignment", "Assignment"),
      colSpan: 6,
    },
    {
      name: "parentEmployeePlanId",
      label: t("employeePlans.parentEmployeePlan", "Parent Employee Plan"),
      type: "select",
      options: employeePlanOptions,
      icon: FileText,
      section: t("employeePlans.assignment", "Assignment"),
      disabled: !!parentId,
      colSpan: 6,
      defaultValue: parentId || undefined,
    },

    // Plan Details Section
    {
      name: "planType",
      label: t("employeePlans.planType", "Plan Type"),
      type: "select",
      options: planTypeOptions,
      required: true,
      icon: Target,
      section: t("employeePlans.planDetails", "Plan Details"),
      colSpan: 4,
    },
    {
      name: "expectedQuantity",
      label: t("employeePlans.expectedQuantity", "Expected Quantity"),
      type: "number",
      required: true,
      icon: Target,
      section: t("employeePlans.planDetails", "Plan Details"),
      colSpan: 4,
    },
    {
      name: "timeframe",
      label: t("employeePlans.timeFrame", "Time Frame"),
      type: "select",
      options: timeframeOptions,
      required: true,
      disabled: timeframeOptions.length === 1,
      icon: Calendar,
      section: t("employeePlans.planDetails", "Plan Details"),
      colSpan: 4,
    },

    // Timeframe Context Section
    {
      name: "quarter",
      label: t("employeePlans.quarter", "Quarter"),
      type: "number",
      placeholder: t("employeePlans.enterQuarter", "Enter quarter (1-4)"),
      icon: Calendar,
      section: t("employeePlans.timeframeContext", "Timeframe Context"),
      hidden:
        watchedTimeframe === TimeFrame.YEAR &&
        (!form.getValues("quarter") ||
          String(form.getValues("quarter")) === "0"),
      colSpan: 4,
      min: 1,
      max: 4,
    },
    {
      name: "month",
      label: t("employeePlans.month", "Month"),
      type: "number",
      placeholder: t("employeePlans.enterMonth", "Enter month (1-12)"),
      icon: Calendar,
      section: t("employeePlans.timeframeContext", "Timeframe Context"),
      hidden:
        ![TimeFrame.MONTH, TimeFrame.WEEK, TimeFrame.DAY].includes(
          watchedTimeframe as TimeFrame
        ) &&
        (!form.getValues("month") || String(form.getValues("month")) === "0"),
      colSpan: 4,
      min: 1,
      max: 12,
    },
    {
      name: "week",
      label: t("employeePlans.week", "Week"),
      type: "number",
      placeholder: t("employeePlans.enterWeek", "Enter week (1-52)"),
      icon: Calendar,
      section: t("employeePlans.timeframeContext", "Timeframe Context"),
      hidden:
        ![TimeFrame.WEEK, TimeFrame.DAY].includes(
          watchedTimeframe as TimeFrame
        ) &&
        (!form.getValues("week") || String(form.getValues("week")) === "0"),
      colSpan: 4,
      min: 1,
      max: 52,
    },
  ];

  // Filter fields based on timeframe
  const filteredFields = employeePlanFormFields.filter((field) => {
    if (field.hidden) return false;
    return true;
  });

  const handleCancel = () => {
    navigate(-1);
  };

  return (
    <div className="min-h-screen bg-gradient-to-br from-slate-50 to-blue-50 p-4 sm:p-6">
      <div className="max-w-4xl mx-auto">
        {/* Header */}
        <motion.div
          initial={{ opacity: 0, y: -20 }}
          animate={{ opacity: 1, y: 0 }}
          className="flex items-center justify-between mb-8">
          <div className="flex items-center space-x-4">
            <Button
              variant="outline"
              size="sm"
              onClick={() => navigate(-1)}
              className="border-gray-300 text-gray-700 hover:bg-gray-50">
              <ArrowLeft className="h-4 w-4 mr-2" />
              Back
            </Button>
            <div>
              <h1 className="text-3xl font-bold bg-gradient-to-r from-gray-800 to-gray-600 bg-clip-text text-transparent">
                {isEdit ? "Edit Employee Plan" : "Create Employee Plan"}
              </h1>
              <p className="text-gray-600 mt-1">
                {isEdit
                  ? "Update employee plan assignment and details"
                  : "Assign a plan to an employee with specific targets"}
              </p>
            </div>
          </div>

          <div className="flex items-center space-x-2 bg-white/80 backdrop-blur-sm rounded-2xl px-4 py-2 shadow-sm border border-gray-200">
            <div
              className={`w-2 h-2 rounded-full ${
                isEdit ? "bg-amber-500" : "bg-green-500"
              } animate-pulse`}></div>
            <span className="text-sm font-medium text-gray-700">
              {isEdit ? "Editing Mode" : "Creation Mode"}
            </span>
          </div>
        </motion.div>

        <motion.div
          initial={{ opacity: 0, y: 20 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ delay: 0.1 }}>
          <Card className="bg-white/80 backdrop-blur-sm border-0 shadow-xl overflow-hidden">
            <CardHeader className="bg-gradient-to-r from-blue-500 to-cyan-500 text-white pb-6">
              <div className="flex items-center space-x-3">
                <div className="w-12 h-12 bg-white/20 rounded-2xl flex items-center justify-center backdrop-blur-sm">
                  {isEdit ? (
                    <FileText className="h-6 w-6 text-white" />
                  ) : (
                    <Plus className="h-6 w-6 text-white" />
                  )}
                </div>
                <div>
                  <CardTitle className="text-2xl font-bold text-white">
                    {isEdit
                      ? t(
                          "employeePlans.updateEmployeePlan",
                          "Update Employee Plan"
                        )
                      : t(
                          "employeePlans.newEmployeePlanAssignment",
                          "New Employee Plan Assignment"
                        )}
                  </CardTitle>
                  <CardDescription className="text-blue-100">
                    {isEdit
                      ? t(
                          "employeePlans.modifyPlanDetails",
                          "Modify the employee plan details below"
                        )
                      : t(
                          "employeePlans.assignPlanWithTimeframe",
                          "Assign plan to employee with specific timeframe and targets"
                        )}
                  </CardDescription>
                </div>
              </div>
            </CardHeader>

            <CardContent className="p-6">
              {/* Parent Plan Info Alert */}
              {parentId && parentEmployeePlanDetail?.data && (
                <Alert className="mb-6 bg-blue-50/80 border-blue-200/50 backdrop-blur-sm">
                  <Info className="h-4 w-4 text-blue-600" />
                  <AlertTitle className="text-blue-900 font-semibold">
                    {t(
                      "employeePlans.creatingSubEmployeePlan",
                      "Creating Sub-Employee Plan"
                    )}
                  </AlertTitle>
                  <AlertDescription className="text-blue-700">
                    {t(
                      "employeePlans.subPlanUnder",
                      "This employee plan will be created under"
                    )}
                    :{" "}
                    <strong className="text-blue-900">
                      {parentEmployeePlanDetail.data.name ||
                        t("employeePlans.parentPlan", "Parent Plan")}
                    </strong>
                  </AlertDescription>
                </Alert>
              )}

              <GenericForm
                form={form}
                fields={filteredFields}
                onSubmit={handleSubmit}
                onCancel={handleCancel}
                isSubmitting={
                  createMutation.isPending || updateMutation.isPending
                }
                submitButtonText={
                  isEdit
                    ? t(
                        "employeePlans.updateEmployeePlan",
                        "Update Employee Plan"
                      )
                    : t(
                        "employeePlans.createEmployeePlan",
                        "Create Employee Plan"
                      )
                }
                cancelButtonText={t("employeePlans.cancel", "Cancel")}
                successMessage={
                  isEdit
                    ? t(
                        "employeePlans.planUpdatedSuccess",
                        "Employee plan updated successfully!"
                      )
                    : t(
                        "employeePlans.planCreatedSuccess",
                        "Employee plan created successfully!"
                      )
                }
                errorMessage={
                  isEdit
                    ? t(
                        "employeePlans.planUpdateFailed",
                        "Failed to update employee plan"
                      )
                    : t(
                        "employeePlans.planCreateFailed",
                        "Failed to create employee plan"
                      )
                }
              />
            </CardContent>
          </Card>
        </motion.div>
      </div>
    </div>
  );
}
