import { TreeViewItem } from "@/shared/common/ui/treeSelect";

import { z } from "zod";
import { t } from "i18next";

const EXTERNAL_LIKE_RECORD_TYPE_KEYS = ["external", "bank"];

const isExternalLikeRecordType = (recordType?: string) =>
  EXTERNAL_LIKE_RECORD_TYPE_KEYS.includes(
    String(recordType || "").toLowerCase(),
  );

export const fileInfoSchema = z.object({
  bucket: z.string().min(1),
  fileName: z.string().min(1),
  contentType: z.string().min(1),
  originalname: z.string().min(1),
  size: z.number().nonnegative(),
});

export const attachmentNameSchema = z.object({
  am: z.string().min(1),
  en: z.string().min(1),
});

export const attachmentSchema = z.object({
  fileInfo: fileInfoSchema,
  name: attachmentNameSchema,
});

export const TreeViewItemSchema: z.ZodType<TreeViewItem> = z.lazy(() =>
  z.object({
    id: z.string(),
    name: z.object({
      en: z.string(),
      am: z.string(),
    }),
    hierarchyType: z.string(),
    children: z.array(z.lazy(() => TreeViewItemSchema)).optional(),
    checked: z.boolean().optional(),
  }),
);

const ReceiverItemSchema = z.object({
  unitId: z.string().optional(),
  name: z
    .union([
      z.string(),
      z.object({
        am: z.string(),
        en: z.string(),
      }),
    ])
    .optional(),
  type: z.enum(["unit", "non_smart"]),
});

const ReceiverGroupSchema = z.object({
  prefix: z.string().optional(),
  suffix: z.string().optional(),
  receivers: z.array(ReceiverItemSchema),
});

const createLetterSchema = z
  .object({
    recordType: z.string().min(1, t("msg.recordTypeRequired")),
    initiationType: z.string().min(1, t("msg.initiationTypeRequired")),
    subject: z.string().min(1, t("msg.subjectRequired")),
    referenceNumber: z.string().optional(),
    preferredLanguage: z.string().min(1, t("msg.preferredLanguageRequired")),
    prefix: z.string().optional(),
    suffix: z.string().optional(),
    body: z.string().min(1, t("msg.bodyRequired")),
    ccPrefix: z.string().optional(),
    ccSuffix: z.string().optional(),
    ReceiversList: z.array(ReceiverGroupSchema).optional(),
    ReceiverList: z.array(ReceiverGroupSchema).optional(),
    nonSmartReceiversList: z.array(ReceiverGroupSchema).optional(),
    ccList: z.array(ReceiverGroupSchema).optional(),
    forYourReferenceList: z.array(ReceiverGroupSchema).optional(),
    groupedItems: z
      .array(
        z.object({
          prefix: z.string().optional(),
          suffix: z.string().optional(),
          values: z.array(z.string()),
        }),
      )
      .optional(),
    groupedCCItems: z
      .array(
        z.object({
          prefix: z.string().optional(),
          suffix: z.string().optional(),
          values: z.array(z.string()),
        }),
      )
      .optional(),
    groupedFYRItems: z
      .array(
        z.object({
          prefix: z.string().optional(),
          suffix: z.string().optional(),
          values: z.array(z.string()),
        }),
      )
      .optional(),
    groupedTreeItems: z
      .array(
        z.object({
          prefix: z.string().optional(),
          suffix: z.string().optional(),
          values: z.array(TreeViewItemSchema),
        }),
      )
      .optional(),
    groupedCCTreeItems: z
      .array(
        z.object({
          prefix: z.string().optional(),
          suffix: z.string().optional(),
          values: z.array(TreeViewItemSchema),
        }),
      )
      .optional(),
    groupedFYRTreeItems: z
      .array(
        z.object({
          prefix: z.string().optional(),
          suffix: z.string().optional(),
          values: z.array(TreeViewItemSchema),
        }),
      )
      .optional(),
    nonSmartOfficeReceiverCCs: z.array(z.string()).optional(),
    nonSmartOfficeReceivers: z.array(z.string()).optional(),
    internalCC: z.array(z.string()).optional(),
    forYourReference: z.array(z.string()).optional(),
    externalCC: z.array(TreeViewItemSchema).optional(),
    receivingUnitIds: z.array(TreeViewItemSchema).optional(),
    forYourReferenceUnitIds: z.array(TreeViewItemSchema).optional(),
    toPositions: z.array(z.string()),
    recordTagIds: z.array(z.string()),
    toEmployees: z.array(z.string()),
    ccEmployees: z.array(z.string()).optional(),
    collaborators: z.array(z.string()).optional(),
    sincerelyText: z.string().trim().min(1, t("msg.sincerelyTextRequired")),
    recordTemplateId: z.string().optional(),
    headerId: z.string().optional().nullable(),
    footerId: z.string().optional().nullable(),
    mode: z.union([z.literal("add"), z.literal("edit")]),
    personalRemark: z.string().optional(),
    isWithTeamSignature: z.boolean(),
    skipOneLevel: z.boolean().optional(),
    letterName: z.string().min(1, t("msg.letterNameRequired")),
    initiatedAs: z.string().min(1, "error"),
    inReplyToIncomingInstanceId: z.string().optional(),
    positionPrefixId: z.string().optional(),
    attachments: z.array(attachmentSchema).optional(),
  })
  .superRefine((data, ctx) => {
    if (isExternalLikeRecordType(data.recordType)) {
      const hasReceiversList = Boolean(
        data.ReceiversList?.some((group) => group.receivers.length > 0),
      );
      const hasGroupedReceivers = Boolean(
        data.groupedItems?.some((group) => group.values.length > 0),
      );
      const hasGroupedTreeReceivers = Boolean(
        data.groupedTreeItems?.some((group) => group.values.length > 0),
      );
      if (
        !data.receivingUnitIds?.length &&
        !data.nonSmartOfficeReceivers?.length &&
        !hasReceiversList &&
        !hasGroupedReceivers &&
        !hasGroupedTreeReceivers
      ) {
        ctx.addIssue({
          code: z.ZodIssueCode.custom,
          message: t("msg.receivingUnitRequired"),
          path: ["receivingUnitIds"],
        });
      }
    }

    const requiresInternalRecipients = [
      "internal",
      "internal_memo",
      "direct",
    ].includes(data.recordType);

    if (requiresInternalRecipients) {
      const hasInternalRecipients =
        Boolean(data.toPositions?.length) || Boolean(data.toEmployees?.length);

      if (!hasInternalRecipients) {
        ctx.addIssue({
          code: z.ZodIssueCode.custom,
          message: t(
            "msg.atLeastOneDepartmentOrUserRequired",
            "At least one department or user is required",
          ),
          path: ["toPositions"],
        });
      }
    }

    if (data.initiationType === "team" && !data.collaborators?.length) {
      ctx.addIssue({
        code: z.ZodIssueCode.custom,
        message: t(
          "msg.collaboratorsRequired",
          "At least one collaborator is required",
        ),
        path: ["collaborators"],
      });
    }
  });

export type FormDataType = z.infer<typeof createLetterSchema>;

export interface AddOrEditRecordState extends FormDataType {
  mode: "add" | "edit";
  recordId?: string;
}
export type CreateOrEditLetter = z.infer<typeof createLetterSchema>;

/** Map API / legacy language strings to the form's "en" | "am" values. */
export const normalizePreferredLanguage = (
  value?: string | null,
  fallback: "en" | "am" = "am",
): "en" | "am" => {
  if (!value) return fallback;
  const normalized = value.trim().toLowerCase();
  if (normalized === "en" || normalized === "am") return normalized;
  if (normalized.startsWith("en")) return "en";
  if (normalized.startsWith("am")) return "am";
  return fallback;
};

const defaultCreateLetterValues: AddOrEditRecordState = {
  recordType: "internal",
  initiationType: "self",
  subject: "",
  preferredLanguage: "am",
  prefix: "",
  suffix: "",
  body: "",
  ccPrefix: "",
  ccSuffix: "",
  ReceiversList: [{ prefix: "", suffix: "", receivers: [] }],
  ReceiverList: [{ prefix: "", suffix: "", receivers: [] }],
  nonSmartReceiversList: [{ prefix: "", suffix: "", receivers: [] }],
  ccList: [{ prefix: "", suffix: "", receivers: [] }],
  forYourReferenceList: [{ prefix: "", suffix: "", receivers: [] }],
  groupedItems: [{ prefix: "", suffix: "", values: [] }],
  groupedCCItems: [{ prefix: "", suffix: "", values: [] }],
  groupedTreeItems: [{ prefix: "", suffix: "", values: [] }],
  groupedCCTreeItems: [{ prefix: "", suffix: "", values: [] }],
  nonSmartOfficeReceivers: [],
  nonSmartOfficeReceiverCCs: [],
  internalCC: [],
  forYourReference: [],
  externalCC: [],
  forYourReferenceUnitIds: [],
  recordTagIds: [],
  toPositions: [],
  toEmployees: [],
  ccEmployees: [],
  collaborators: [],
  sincerelyText: "ከሠላምታ ጋር",
  mode: "add",
  recordTemplateId: undefined,
  headerId: "",
  footerId: "",
  personalRemark: "",
  isWithTeamSignature: false,
  skipOneLevel: false,
  letterName: "",
  initiatedAs: "self",
  inReplyToIncomingInstanceId: "",
  positionPrefixId: "",
  referenceNumber: "",
  // sincerelyText:"Sincerly"
};
const DEFAULT_VALUES: CreateOrEditLetter = {
  recordType: "internal",
  initiationType: "self",
  subject: "",
  preferredLanguage: "am",
  prefix: "",
  suffix: "",
  body: "",
  ccPrefix: "",
  ccSuffix: "",
  ReceiversList: [{ prefix: "", suffix: "", receivers: [] }],
  ReceiverList: [{ prefix: "", suffix: "", receivers: [] }],
  nonSmartReceiversList: [{ prefix: "", suffix: "", receivers: [] }],
  ccList: [{ prefix: "", suffix: "", receivers: [] }],
  forYourReferenceList: [{ prefix: "", suffix: "", receivers: [] }],
  groupedItems: [{ prefix: "", suffix: "", values: [] }],
  groupedCCItems: [{ prefix: "", suffix: "", values: [] }],
  groupedTreeItems: [{ prefix: "", suffix: "", values: [] }],
  groupedCCTreeItems: [{ prefix: "", suffix: "", values: [] }],
  nonSmartOfficeReceivers: [],
  nonSmartOfficeReceiverCCs: [],
  internalCC: [],
  forYourReference: [],
  externalCC: [],
  forYourReferenceUnitIds: [],
  recordTagIds: [],
  toPositions: [],
  toEmployees: [],
  ccEmployees: [],
  collaborators: [],
  sincerelyText: "ከሠላምታ ጋር",
  mode: "add",
  recordTemplateId: undefined,
  personalRemark: "",
  isWithTeamSignature: false,
  skipOneLevel: false,
  footerId: "",
  headerId: "",
  letterName: "",
  initiatedAs: "self",
  inReplyToIncomingInstanceId: "",
  positionPrefixId: "",
};

export { createLetterSchema, defaultCreateLetterValues };
