import { z } from "zod";
import { normalizeAllowedContentTypes } from "../../utils/appUtils";

const MAX_FILE_SIZE = 5 * 1024 * 1024; // 5MB
const ALLOWED_TYPES = [
  "application/pdf",
  "image/png",
  "image/jpg",
  "image/jpeg",
];

export const AttachmentSchema = z.object({
  invoiceAttachmentTypeId: z.string().nullable(),
  fileName: z.string().min(1, { message: "Filename is required" }),
  base64Data: z.string().nullable(),
  contentType: z.string().refine((val) => ALLOWED_TYPES.includes(val), {
    message: "Only PDF, PNG, JPG, or JPEG files are allowed",
  }),
  fileSize: z.number().max(MAX_FILE_SIZE, {
    message: "File size must be less than or equal to 5MB",
  }),
  description: z.string().optional().default(""),
  isActive: z.boolean().default(true),
  documentId: z.string().nullable().default(null),
});

export const PurchaseSchema = z.object({
  title: z.string().min(1, { message: "Title is required" }),
  projectId: z.string().min(1, { message: "Project is required" }),
  organizationId: z.string().min(1, { message: "Organization is required" }),
  billingAddress: z.string().min(1, { message: "Address is required" }),
  shippingAddress: z.string().min(1, { message: "Address is required" }),

  purchaseOrderNumber: z.string().nullable(),
  purchaseOrderDate: z.coerce.date().nullable(),

  supplierId: z.string().min(1, { message: "Supplier is required" }),

  proformaInvoiceNumber: z.string().nullable(),
  proformaInvoiceDate: z.coerce.date().nullable(),
  proformaInvoiceAmount: z.coerce.number().optional(),

  invoiceNumber: z.string().nullable(),
  invoiceDate: z.coerce.date().nullable(),
  eWayBillNumber: z.string().nullable(),
  eWayBillDate: z.coerce.date().nullable(),
  invoiceReferenceNumber: z.string().nullable(),
  acknowledgmentDate: z.coerce.date().nullable(),
  acknowledgmentNumber: z.string().nullable(),

  baseAmount: z
    .number()
    .or(z.nan()) // allow NaN
    .transform((val) => (Number.isNaN(val) ? null : val)),

  taxAmount: z
    .number()
    .or(z.nan()) // allow NaN
    .transform((val) => (Number.isNaN(val) ? null : val)),
  totalAmount: z
    .number()
    .or(z.nan()) // allow NaN
    .transform((val) => (Number.isNaN(val) ? null : val)),
  paymentDueDate: z.coerce.date().nullable(),
  transportCharges: z
    .number()
    .or(z.nan()) // allow NaN
    .transform((val) => (Number.isNaN(val) ? null : val)),
  description: z.string(),
  invoiceAttachmentTypeId: z.string().nullable(),
  attachments: z.array(AttachmentSchema),
});

export const defaultPurchaseValue = {
  title: "",
  projectId: "",
  organizationId: "",
  billingAddress: "",
  shippingAddress: "",
  purchaseOrderNumber: null,
  purchaseOrderDate: null,

  supplierId: "",

  proformaInvoiceNumber: null,
  proformaInvoiceDate: null,
  proformaInvoiceAmount: 0,

  invoiceNumber: null,
  invoiceDate: null,
  eWayBillNumber: null,
  eWayBillDate: null,
  invoiceReferenceNumber: null,
  acknowledgmentNumber: null,
  acknowledgmentDate: null,

  baseAmount: 0,
  taxAmount: 0,
  totalAmount: 0,
  paymentDueDate: null,
  transportCharges: 0,
  description: "",
  invoiceAttachmentTypeId: null,
  attachments: [],
};

export const getStepFields = (stepIndex) => {
  const stepFieldMap = {
    0: [
      "title",
      "projectId",
      "organizationId",
      "supplierId",
      "billingAddress",
      "shippingAddress",
      "purchaseOrderNumber",
      "purchaseOrderDate",
      "proformaInvoiceNumber",
      "proformaInvoiceDate",
      "proformaInvoiceAmount",
    ],
    1: [
      "invoiceNumber",
      "invoiceDate",
      "eWayBillNumber",
      "eWayBillDate",
      "invoiceReferenceNumber",
      "acknowledgmentNumber",
      "acknowledgmentDate",
    ],
    2: [
      "baseAmount",
      "taxAmount",
      "totalAmount",
      "transportCharges",
      "paymentDueDate",
      "invoiceAttachmentTypeId",
      "description",
      "attachments",
    ],
  };

  return stepFieldMap[stepIndex] || [];
};

export const SingleAttachmentSchema = z.object({
  fileName: z.string().min(1, { message: "File name is required" }),
  base64Data: z.string().min(1, { message: "File data is required" }),
  invoiceAttachmentTypeId: z.string().nullable(),

  contentType: z
    .string()
    .min(1, { message: "MIME type is required" })
    .refine(
      (val) =>
        ["application/pdf", "image/jpeg", "image/jpg", "image/png"].includes(
          val
        ),
      {
        message: "File type must be PDF, JPG, JPEG or PNG",
      }
    ),

  fileSize: z
    .number()
    .int()
    .nonnegative("fileSize must be ≥ 0")
    .max(5 * 1024 * 1024, "File size must be ≤ 5MB"),

  description: z.string().optional().default(""),
  isActive: z.boolean(),
});

export const DeliveryChallanSchema = z.object({
  deliveryChallanNumber: z
    .string()
    .min(1, { message: "Challan Number required" }),
  invoiceAttachmentTypeId: z.string().nullable(),
  deliveryChallanDate: z.string().min(1, { message: "Deliver date required" }),
  description: z.string().min(1, { message: "Description required" }),
  attachment: z
    .any()
    .refine((val) => val && typeof val === "object" && !!val.base64Data, {
      message: "Please upload document",
    }),
});

export const DeliveryChallanDefaultValue = {
  deliveryChallanNumber: "",
  deliveryChallanDate: "",
  description: "",
  attachment: null,
  invoiceAttachmentTypeId: null,
};

export const AddPurchasePayment = z.object({
  paymentReceivedDate: z.string().min(1, { message: "Date is required" }),
  transactionId: z.string().min(1, "Transaction ID is required"),
  amount: z.number().min(1, "Amount must be greater than zero"),
  comment: z.string().min(1, { message: "Comment required" }),
  paymentAdjustmentHeadId: z
    .string()
    .min(1, { message: "Payment Type required" }),
});
export const defaultPurchasePayment = {
  paymentReceivedDate: null,
  transactionId: "",
  amount: 0,
  comment: "",
  paymentAdjustmentHeadId: "",
};
