import { DEFAULT_RULES } from "./types";

export type DocumentDraft = {
  type: string;
  label: string;
  required: boolean;
  accept: string;
  max_size_kb: string;
};

export type FormFieldDraft = {
  key: string;
  label: string;
  type: "text" | "textarea" | "number" | "select" | "date";
  required: boolean;
  options: string;
};

export type GradeRulesDraft = {
  enabled: boolean;
  allowBoys: boolean;
  allowGirls: boolean;
  min_age: string;
  max_age: string;
  min_previous_gpa: string;
  min_previous_gpa_mode: "block" | "warn";
  rules_text: string;
  rules_html: string;
  admission_free: boolean;
  admission_amount: string;
  payOnline: boolean;
  payCardToCard: boolean;
  card_bank: string;
  card_number: string;
  card_holder: string;
  seat_quota: string;
  waitlist_enabled: boolean;
  waitlist_max: string;
  documents: DocumentDraft[];
  selectedDocumentCatalogIds: number[];
  formFields: FormFieldDraft[];
  selectedFormFieldCatalogIds: number[];
  is_active: boolean;
  /** مرحله بعد از ثبت‌نام: تماس بعدی یا آزمون */
  followupMode: "contact_later" | "exam";
  contactLaterMessage: string;
  examTitle: string;
  examAddress: string;
  examNotes: string;
  examLat: string;
  examLng: string;
  examScheduleTitle: string;
  examStartsAt: string;
  examEndsAt: string;
};

export const DEFAULT_DOCUMENT: DocumentDraft = {
  type: "",
  label: "",
  required: true,
  accept: "image/jpeg,image/png,application/pdf",
  max_size_kb: "5120",
};

export const DEFAULT_FIELD: FormFieldDraft = {
  key: "",
  label: "",
  type: "text",
  required: false,
  options: "",
};

function normalizeAllowedGenders(raw: unknown): string[] {
  if (Array.isArray(raw)) {
    return raw.map((g) => String(g)).filter((g) => g === "male" || g === "female");
  }
  if (raw && typeof raw === "object") {
    return Object.values(raw as Record<string, unknown>)
      .map((g) => String(g))
      .filter((g) => g === "male" || g === "female");
  }
  return ["male", "female"];
}

export function rulesToDraft(rules: Record<string, unknown>): GradeRulesDraft {
  const fee = (rules.admission_fee as { free?: boolean; amount?: number }) ?? {};
  const card = (rules.card_to_card_info as { bank?: string; card?: string; holder?: string }) ?? {};
  const genders = normalizeAllowedGenders(rules.allowed_genders);
  const methods = (rules.payment_methods as string[]) ?? ["online", "card_to_card"];
  const docs = (rules.required_documents as Array<Record<string, unknown>>) ?? [];
  const fields = (rules.educational_form_fields as Array<Record<string, unknown>>) ?? [];
  const followup = (rules.followup as Record<string, unknown>) ?? {};
  const exam = (followup.exam as Record<string, unknown>) ?? {};
  const map = (exam.map as { lat?: number; lng?: number } | null) ?? null;
  const modeRaw = String(followup.mode ?? "");
  const followupMode: "contact_later" | "exam" =
    modeRaw === "exam" ? "exam" : "contact_later";

  return {
    enabled: rules.enabled !== false,
    allowBoys: genders.includes("male"),
    allowGirls: genders.includes("female"),
    min_age: rules.min_age != null ? String(rules.min_age) : "",
    max_age: rules.max_age != null ? String(rules.max_age) : "",
    min_previous_gpa: rules.min_previous_gpa != null ? String(rules.min_previous_gpa) : "",
    min_previous_gpa_mode: (rules.min_previous_gpa_mode as "block" | "warn") ?? "warn",
    rules_text: String(rules.rules_text ?? ""),
    rules_html: String(rules.rules_html ?? ""),
    admission_free: Boolean(fee.free),
    admission_amount: String(fee.amount ?? 0),
    payOnline: methods.includes("online"),
    payCardToCard: methods.includes("card_to_card"),
    card_bank: String(card.bank ?? ""),
    card_number: String(card.card ?? ""),
    card_holder: String(card.holder ?? ""),
    seat_quota: rules.seat_quota != null ? String(rules.seat_quota) : "",
    waitlist_enabled: rules.waitlist_enabled !== false,
    waitlist_max: rules.waitlist_max != null ? String(rules.waitlist_max) : "",
    documents: docs.filter((d) => !d.catalog_id).length
      ? docs
          .filter((d) => !d.catalog_id)
          .map((d) => ({
            type: String(d.type ?? ""),
            label: String(d.label ?? ""),
            required: d.required !== false,
            accept: ((d.accept as string[]) ?? ["image/jpeg", "image/png"]).join(","),
            max_size_kb: String(d.max_size_kb ?? 5120),
          }))
      : [{ ...DEFAULT_DOCUMENT }],
    selectedDocumentCatalogIds: Array.isArray(rules.selected_document_catalog_ids)
      ? (rules.selected_document_catalog_ids as number[]).map(Number)
      : docs
          .map((d) => Number(d.catalog_id))
          .filter((id) => Number.isFinite(id) && id > 0),
    formFields: fields.filter((f) => !f.catalog_id).length
      ? fields
          .filter((f) => !f.catalog_id)
          .map((f) => ({
            key: String(f.key ?? ""),
            label: String(f.label ?? ""),
            type: (f.type as FormFieldDraft["type"]) ?? "text",
            required: Boolean(f.required),
            options: ((f.options as Array<{ value: string; label: string }>) ?? [])
              .map((o) => o.label || o.value)
              .filter(Boolean)
              .join("\n"),
          }))
      : [{ ...DEFAULT_FIELD }],
    selectedFormFieldCatalogIds: Array.isArray(rules.selected_form_field_catalog_ids)
      ? (rules.selected_form_field_catalog_ids as number[]).map(Number)
      : fields
          .map((f) => Number(f.catalog_id))
          .filter((id) => Number.isFinite(id) && id > 0),
    is_active: true,
    followupMode,
    contactLaterMessage: String(followup.contact_message ?? ""),
    examTitle: String(exam.title ?? ""),
    examAddress: String(exam.address ?? ""),
    examNotes: String(exam.notes ?? ""),
    examLat: map?.lat != null ? String(map.lat) : "",
    examLng: map?.lng != null ? String(map.lng) : "",
    examScheduleTitle: String(exam.schedule_title ?? ""),
    examStartsAt: String(exam.starts_at ?? "").slice(0, 10),
    examEndsAt: String(exam.ends_at ?? "").slice(0, 10),
  };
}

function slugifyOption(label: string): string {
  const trimmed = label.trim();
  if (!trimmed) return "";
  // Keep Persian/Latin letters and digits; spaces → underscore
  return trimmed
    .replace(/\s+/g, "_")
    .replace(/[^\w\u0600-\u06FF_]/g, "")
    .slice(0, 64) || trimmed;
}

/** Parse select options: one label per line (preferred) or legacy value:label,value:label */
export function parseSelectOptions(raw: string): Array<{ value: string; label: string }> {
  const text = raw.trim();
  if (!text) return [];

  const byLine = text.split(/\r?\n/).map((l) => l.trim()).filter(Boolean);
  if (byLine.length > 1 || !text.includes(",")) {
    return byLine.map((label) => {
      if (label.includes(":") && !label.includes(" ")) {
        const [value, ...rest] = label.split(":");
        const lbl = rest.join(":").trim() || value.trim();
        return { value: value.trim() || slugifyOption(lbl), label: lbl };
      }
      return { value: slugifyOption(label), label };
    });
  }

  return text.split(",").map((part) => {
    const piece = part.trim();
    if (!piece) return null;
    if (piece.includes(":")) {
      const [value, ...rest] = piece.split(":");
      const label = rest.join(":").trim() || value.trim();
      return { value: (value || slugifyOption(label)).trim(), label };
    }
    return { value: slugifyOption(piece), label: piece };
  }).filter((o): o is { value: string; label: string } => Boolean(o));
}

function simpleTextToHtml(text: string) {
  if (!text.trim()) return "";
  const lines = text.split("\n").filter(Boolean);
  return `<h3>شرایط ثبت‌نام</h3><ul>${lines.map((l) => `<li>${l.replace(/^\d+\.\s*/, "")}</li>`).join("")}</ul>`;
}

export function draftToRules(draft: GradeRulesDraft, base: Record<string, unknown>) {
  const genders: string[] = [];
  if (draft.allowBoys) genders.push("male");
  if (draft.allowGirls) genders.push("female");

  const methods: string[] = [];
  if (draft.payOnline) methods.push("online");
  if (draft.payCardToCard) methods.push("card_to_card");

  const required_documents = draft.documents
    .filter((d) => d.label.trim())
    .map((d) => ({
      type: d.type.trim() || d.label.trim().replace(/\s+/g, "_"),
      label: d.label.trim(),
      required: d.required,
      accept: d.accept.split(",").map((s) => s.trim()).filter(Boolean),
      max_size_kb: Number(d.max_size_kb) || 5120,
      multiple: false,
    }));

  const educational_form_fields = draft.formFields
    .filter((f) => f.label.trim())
    .map((f) => ({
      key: f.key.trim() || f.label.trim().replace(/\s+/g, "_"),
      label: f.label.trim(),
      type: f.type,
      required: f.required,
      ...(f.type === "select" && f.options
        ? { options: parseSelectOptions(f.options) }
        : {}),
    }));

  return {
    ...base,
    enabled: draft.enabled,
    // فقط همان‌هایی که تیک خورده‌اند ذخیره می‌شود (بدون برگشت اجباری به هر دو)
    allowed_genders: genders,
    min_age: draft.min_age ? Number(draft.min_age) : null,
    max_age: draft.max_age ? Number(draft.max_age) : null,
    birth_date_from: null,
    birth_date_to: null,
    min_previous_gpa: draft.min_previous_gpa ? Number(draft.min_previous_gpa) : null,
    min_previous_gpa_mode: draft.min_previous_gpa_mode,
    rules_text: draft.rules_text,
    rules_html: simpleTextToHtml(draft.rules_text),
    required_documents,
    selected_document_catalog_ids: draft.selectedDocumentCatalogIds,
    educational_form_fields,
    selected_form_field_catalog_ids: draft.selectedFormFieldCatalogIds,
    admission_fee: draft.admission_free
      ? { free: true, amount: 0, currency: "IRR" }
      : { free: false, amount: Number(draft.admission_amount) || 0, currency: "IRR" },
    payment_methods: methods.length ? methods : ["online", "card_to_card"],
    card_to_card_info: {
      bank: draft.card_bank,
      card: draft.card_number,
      holder: draft.card_holder,
    },
    seat_quota: draft.seat_quota ? Number(draft.seat_quota) : null,
    waitlist_enabled: draft.waitlist_enabled,
    waitlist_max: draft.waitlist_max ? Number(draft.waitlist_max) : null,
    evaluation_steps: ["document_review"],
    followup: {
      mode: draft.followupMode,
      contact_message: draft.contactLaterMessage.trim(),
      exam: {
        title: draft.examTitle.trim(),
        address: draft.examAddress.trim(),
        notes: draft.examNotes.trim(),
        map:
          draft.examLat !== "" && draft.examLng !== ""
            ? { lat: Number(draft.examLat), lng: Number(draft.examLng) }
            : null,
        schedule_title: draft.examScheduleTitle.trim(),
        starts_at: draft.examStartsAt || null,
        ends_at: draft.examEndsAt || null,
      },
    },
  };
}

const STEP_RULE_KEYS: Record<number, string[]> = {
  1: ["enabled"],
  2: ["allowed_genders", "min_age", "max_age", "min_previous_gpa", "min_previous_gpa_mode"],
  3: ["rules_text", "rules_html"],
  4: ["required_documents", "selected_document_catalog_ids"],
  5: ["educational_form_fields", "selected_form_field_catalog_ids"],
  6: ["admission_fee", "payment_methods", "card_to_card_info"],
  7: ["seat_quota", "waitlist_enabled", "waitlist_max"],
  8: ["followup", "evaluation_steps"],
};

/** فقط فیلدهای مربوط به یک مرحله wizard را روی base اعمال می‌کند. */
export function draftToRulesForStep(
  stepId: number,
  draft: GradeRulesDraft,
  base: Record<string, unknown>,
): Record<string, unknown> {
  const full = draftToRules(draft, base) as Record<string, unknown>;
  const keys = STEP_RULE_KEYS[stepId] ?? [];
  const merged: Record<string, unknown> = { ...base };

  for (const key of keys) {
    if (key in full) {
      merged[key] = full[key];
    }
  }

  return merged;
}

export function emptyRulesTemplate(): Record<string, unknown> {
  return structuredClone(DEFAULT_RULES);
}
