import FullScreenLoading from "@/components/FullScreenLoading";
import notification from "@/components/notificationGlobal";
import SuccessPengajuan from "@/components/SuccessPengajuanSurat";
import apiFetch from "@/lib/apiFetch";
import { fromSlug, toSlug } from "@/server/lib/slug_converter";
import {
  ActionIcon,
  Badge,
  Box,
  Button,
  Card,
  Container,
  Divider,
  FileInput,
  Flex,
  Grid,
  Group,
  Modal,
  Select,
  Stack,
  Text,
  TextInput,
  Tooltip,
} from "@mantine/core";
import { DateInput } from "@mantine/dates";
import { useDisclosure, useShallowEffect } from "@mantine/hooks";
import {
  IconBuildingCommunity,
  IconCategory,
  IconFiles,
  IconInfoCircle,
  IconNotes,
  IconPhone,
  IconUpload
} from "@tabler/icons-react";
import dayjs from "dayjs";
import "dayjs/locale/id";
import React, { useState } from "react";
import { useLocation, useNavigate } from "react-router-dom";
import useSWR from "swr";

type DataItem = {
  key: string;
  value: string;
  required: boolean;
};

type FormSurat = {
  kategoriId: string;
  nama: string;
  phone: string;
  dataPelengkap: DataItem[];
  syaratDokumen: DataItem[];
};

type ErrorState = Record<string, string | null>;

export default function FormSurat() {
  const [errors, setErrors] = useState<ErrorState>({});
  const [opened, { open, close }] = useDisclosure(false);
  const [noPengajuan, setNoPengajuan] = useState("");
  const [submitLoading, setSubmitLoading] = useState(false);
  const navigate = useNavigate();
  const { search } = useLocation();
  const query = new URLSearchParams(search);
  const jenisSurat = query.get("jenis");
  const { data, mutate, isLoading } = useSWR("category-pelayanan-list", () =>
    apiFetch.api.pelayanan.category.get(),
  );
  const [jenisSuratFix, setJenisSuratFix] = useState({ name: "", id: "" });
  const [dataSurat, setDataSurat] = useState<any>({});
  const [formSurat, setFormSurat] = useState<FormSurat>({
    nama: "",
    phone: "",
    kategoriId: "",
    dataPelengkap: [],
    syaratDokumen: [],
  });

  const listCategory = data?.data || [];

  function onResetAll() {
    setNoPengajuan("");
    setSubmitLoading(false);
    setFormSurat({
      nama: "",
      phone: "",
      kategoriId: "",
      dataPelengkap: [],
      syaratDokumen: [],
    });
  }

  function onGetJenisSurat() {
    try {
      if (!jenisSurat || jenisSurat == "null") {
        setJenisSuratFix({ name: "", id: "" });
      } else {
        const namaJenis = fromSlug(jenisSurat);
        const data = listCategory.find((item: any) => item.name.toUpperCase() == namaJenis.toUpperCase());
        if (!data) return;
        setJenisSuratFix(data);
      }
    } catch (error) {
      console.error(error);
    }
  }

  async function getDetailJenisSurat() {
    try {
      const get: any = await apiFetch.api.pelayanan.category.detail.get({
        query: {
          id: jenisSuratFix.id,
        },
      });

      setDataSurat(get.data);
      setFormSurat({
        kategoriId: jenisSuratFix.id,
        nama: "",
        phone: "",
        dataPelengkap: (get.data?.dataPelengkap || []).map(
          (item: { key: string, required: boolean }) => ({
            key: item.key,
            value: "",
            required: item.required
          }),
        ),
        syaratDokumen: (get.data?.syaratDokumen || []).map(
          (item: { key: string, required: boolean }) => ({
            key: item.key,
            value: "",
            required: item.required
          }),
        ),
      });
    } catch (error) {
      console.error(error);
    }
  }

  useShallowEffect(() => {
    mutate();
  }, []);

  useShallowEffect(() => {
    if (listCategory.length > 0) {
      onGetJenisSurat();
    }
  }, [jenisSurat, listCategory]);

  useShallowEffect(() => {
    if (jenisSuratFix.id != "") {
      getDetailJenisSurat();
    }
  }, [jenisSuratFix.id]);

  function onChecking() {
    const hasError = Object.values(errors).some((v) => v);

    if (hasError) {
      return notification({
        title: "Gagal",
        message: "Masih ada form yang belum valid",
        type: "error",
      });
    }

    const isFormKosong = Object.values(formSurat).some((value) => {
      if (Array.isArray(value)) {
        return value.some(
          (item) =>
            (typeof item.value === "string" && item.value.trim() === "" && item.required) || (typeof item.value === "object" && item.value === null && item.required),
        );
      }
      return typeof value === "string" && value.trim() === "";
    });

    if (isFormKosong) {
      return notification({
        title: "Gagal",
        message: "Silahkan lengkapi form surat",
        type: "error",
      });
    }

    open();
  }

  async function onSubmit() {
    try {
      setSubmitLoading(true);
      // 🔥 CLONE state SEKALI
      let finalFormSurat = structuredClone(formSurat);

      // 2️⃣ Upload satu per satu
      for (const itemUpload of finalFormSurat.syaratDokumen) {
        const updImg = await apiFetch.api.pengaduan.upload.post({
          file: itemUpload.value,
          folder: "syarat-dokumen",
        });

        if (updImg.status === 200) {
          // 🔥 UPDATE OBJECT LOKAL (BUKAN STATE)
          finalFormSurat.syaratDokumen = updateArrayByKey(
            finalFormSurat.syaratDokumen,
            itemUpload.key,
            updImg.data?.filename || "",
          );
        }
      }

      // 3️⃣ SET STATE SEKALI (optional, untuk UI)
      setFormSurat(finalFormSurat);

      // 4️⃣ SUBMIT KE API
      const res = await apiFetch.api.pelayanan.create.post(finalFormSurat);

      if (res.status === 200) {
        setNoPengajuan(res.data?.noPengajuan || "");
      } else {
        notification({
          title: "Gagal",
          message:
            "Pengajuan surat gagal dibuat, silahkan coba beberapa saat lagi",
          type: "error",
        });
      }
    } catch (error) {
      notification({
        title: "Gagal",
        message: "Server Error",
        type: "error",
      });
    } finally {
      setSubmitLoading(false);
    }
  }

  function updateArrayByKey(
    list: DataItem[],
    targetKey: string,
    value: string,
  ): DataItem[] {
    return list.map((item) =>
      item.key === targetKey ? { ...item, value } : item,
    );
  }


  function validateField(key: string, value: any) {
    const stringValue = String(value ?? "").trim();

    // wajib diisi
    if (!stringValue) {
      return "Field wajib diisi";
    }

    // 🔥 semua key yang mengandung "nik"
    if (key.toLowerCase().includes("nik")) {
      if (!/^\d+$/.test(stringValue)) {
        return "NIK harus berupa angka";
      }

      if (stringValue.length !== 16) {
        return "NIK harus 16 digit";
      }
    }

    return null;
  }


  function validationForm({
    key,
    value,
  }: {
    key: "nama" | "phone" | "dataPelengkap" | "syaratDokumen";
    value: any;
  }) {
    if (key === "dataPelengkap" || key === "syaratDokumen") {
      if (value.required == true) {
        const errorMsg = validateField(value.key, value.value);

        setErrors((prev) => ({
          ...prev,
          [value.key]: errorMsg,
        }));
      }
      setFormSurat((prev) => ({
        ...prev,
        [key]: updateArrayByKey(prev[key], value.key, value.value),
      }));
    } else {
      const keyFix = key == "nama" ? "nama_kontak" : key;
      const errorMsg = validateField(keyFix, value);

      setErrors((prev) => ({
        ...prev,
        [keyFix]: errorMsg,
      }));

      setFormSurat({
        ...formSurat,
        [key]: value,
      });
    }
  }


  return (
    <Container size="md" w={"100%"} pb={"lg"}>
      <Modal
        opened={opened}
        onClose={close}
        title={"Konfirmasi"}
        overlayProps={{ backgroundOpacity: 0.55, blur: 3 }}
      >
        <Stack gap="sm">
          <Text>Apakah anda yakin ingin mengirim pengajuan surat ini?</Text>
          <Group justify="center" grow>
            <Button variant="light" onClick={close}>
              Tidak
            </Button>
            <Button
              variant="filled"
              color="green"
              onClick={() => {
                onSubmit();
                close();
              }}
            >
              Ya
            </Button>
          </Group>
        </Stack>
      </Modal>
      <FullScreenLoading visible={submitLoading} />
      {noPengajuan != "" ? (
        <SuccessPengajuan
          noPengajuan={noPengajuan}
          onClose={() => {
            onResetAll();
            navigate("/darmasaba/surat");
          }}
          category="create"
        />
      ) : (
        <Box>
          <Stack gap="lg">
            <Group justify="space-between" align="center">
              <Group align="center">
                <IconBuildingCommunity size={28} />
                <div>
                  <Text fw={800} size="xl">
                    Layanan Pengajuan Surat Administrasi
                  </Text>
                  <Text size="sm" c="dimmed">
                    Formulir resmi untuk mengajukan berbagai jenis surat
                    administrasi desa/kelurahan secara online.
                  </Text>
                </div>
              </Group>
              <Group>
                <Badge radius="sm">Form Length: 4 Sections</Badge>
              </Group>
            </Group>
            <Stack gap="lg">
              <FormSection
                title="Jenis Surat Pengajuan"
                icon={<IconCategory size={16} />}
              >
                <Grid>
                  <Grid.Col span={12}>
                    <Select
                      allowDeselect={false}
                      label={
                        <FieldLabel
                          label="Jenis Surat"
                          hint="Jenis surat yang ingin diajukan"
                        />
                      }
                      placeholder="Pilih jenis surat"
                      data={listCategory.map((item: any) => ({
                        value: item.name,
                        label: item.name,
                      }))}
                      value={jenisSuratFix.name == "" ? null : jenisSuratFix.name}
                      onChange={(value) => {
                        const slug = toSlug(String(value));
                        navigate("/darmasaba/surat?jenis=" + slug);
                      }}
                    />
                  </Grid.Col>
                </Grid>
              </FormSection>

              {/* Kontak Section */}
              <FormSection
                title="Kontak"
                icon={<IconPhone size={16} />}
                description="Informasi kontak yg dapat dihubungi"
              >
                <Grid>
                  <Grid.Col span={6}>
                    <TextInput
                      label={<FieldLabel label="Nama" hint="Nama kontak" required />}
                      placeholder="Budi Setiawan"
                      value={formSurat.nama}
                      error={errors.nama_kontak}
                      onChange={(e) =>
                        validationForm({ key: "nama", value: e.target.value })
                      }
                    />
                  </Grid.Col>

                  <Grid.Col span={6}>
                    <TextInput
                      label={
                        <FieldLabel
                          required
                          label="Nomor Telephone"
                          hint="Nomor telephone yang dapat dihubungi / terhubung dengan whatsapp"
                        />
                      }
                      placeholder="08123456789"
                      value={formSurat.phone}
                      error={errors.phone}
                      type="number"
                      onChange={(e) =>
                        validationForm({ key: "phone", value: e.target.value })
                      }
                    />
                  </Grid.Col>
                </Grid>
              </FormSection>

              {jenisSuratFix.id != "" &&
                dataSurat &&
                dataSurat.dataPelengkap && (
                  <>
                    <FormSection
                      title="Data Yang Diperlukan"
                      description="Data yang diperlukan untuk mengajukan surat"
                      icon={<IconNotes size={16} />}
                    >
                      <Grid>
                        {dataSurat.dataPelengkap.map(
                          (item: any, index: number) => (
                            <Grid.Col span={6} key={index}>
                              {item.type == "enum" ? (
                                <Select
                                  allowDeselect={false}
                                  label={
                                    <FieldLabel
                                      label={item.name}
                                      hint={item.desc}
                                      required={item.required}
                                    />
                                  }
                                  data={item.options ?? []}
                                  placeholder={item.name}
                                  onChange={(e) => {
                                    validationForm({
                                      key: "dataPelengkap",
                                      value: { key: item.key, value: e, required: item.required },
                                    });
                                  }}
                                  value={
                                    formSurat.dataPelengkap.find(
                                      (n: any) => n.key == item.key,
                                    )?.value
                                  }
                                />
                              ) : item.type == "date" ? (
                                <DateInput
                                  locale="id"
                                  valueFormat="DD MMMM YYYY"
                                  label={
                                    <FieldLabel
                                      label={item.name}
                                      hint={item.desc}
                                      required={item.required}
                                    />
                                  }
                                  placeholder={item.name}
                                  onChange={(e) => {
                                    const formatted = e
                                      ? dayjs(e)
                                        .locale("id")
                                        .format("DD MMMM YYYY")
                                      : "";
                                    validationForm({
                                      key: "dataPelengkap",
                                      value: {
                                        key: item.key,
                                        value: formatted,
                                        required: item.required,
                                      },
                                    });
                                  }}
                                />
                              ) : (
                                <TextInput
                                  error={errors[item.key]}
                                  type={item.type}
                                  label={
                                    <FieldLabel
                                      label={item.name}
                                      hint={item.desc}
                                      required={item.required}
                                    />
                                  }
                                  placeholder={item.name}
                                  onChange={(e) =>
                                    validationForm({
                                      key: "dataPelengkap",
                                      value: {
                                        key: item.key,
                                        value: e.target.value,
                                        required: item.required,
                                      },
                                    })
                                  }
                                  value={
                                    formSurat.dataPelengkap.find(
                                      (n: any) => n.key == item.key,
                                    )?.value
                                  }
                                  rightSection={
                                    item.satuan != null &&
                                    <Text mr={"lg"}>{item.satuan}</Text>
                                  }
                                />
                              )}
                            </Grid.Col>
                          ),
                        )}
                      </Grid>
                    </FormSection>

                    <FormSection
                      title="Syarat Dokumen"
                      description="Syarat dokumen yang diperlukan"
                      icon={<IconFiles size={16} />}
                    >
                      <Grid>
                        {dataSurat.syaratDokumen.map(
                          (item: any, index: number) => (
                            <Grid.Col span={6} key={index}>
                              <FileInputWrapper
                                label={item.desc}
                                placeholder={"Upload file "}
                                accept="image/*,application/pdf"
                                onChange={(file) =>
                                  validationForm({
                                    key: "syaratDokumen",
                                    value: { key: item.key, value: file },
                                  })
                                }
                                name={item.name}
                                required={item.required}
                              />
                            </Grid.Col>
                          ),
                        )}
                      </Grid>
                    </FormSection>

                    {/* Actions */}
                    <Group justify="right" mt="md">
                      {/* <Button variant="default" onClick={() => { }}>
                    Reset
                  </Button> */}
                      <Button onClick={onChecking}>Kirim</Button>
                    </Group>
                  </>
                )}
            </Stack>
          </Stack>
        </Box>
      )}
    </Container>
  );
}

function FieldLabel({ label, hint, required = false, }: { label: string; hint?: string; required?: boolean; }) {
  return (
    <Group justify="apart" gap="xs" align="center">
      <Group gap={4} align="center">
        <Text fw={600}>
          {label}
          {required && (
            <Text span c="red" ml={4}>
              *
            </Text>
          )}
        </Text>
      </Group>

      {hint && (
        <Tooltip label={hint} withArrow>
          <ActionIcon size={24} variant="subtle">
            <IconInfoCircle size={16} />
          </ActionIcon>
        </Tooltip>
      )}
    </Group>
  );
}


function FormSection({
  title,
  icon,
  children,
  description,
}: {
  title: string;
  icon?: React.ReactNode;
  children: React.ReactNode;
  description?: string;
}) {
  return (
    <Card radius="md" shadow="sm" withBorder>
      <Group justify="apart" align="center" mb="xs">
        <Group align="center" gap="xs">
          {icon}
          <Text fw={700}>{title}</Text>
        </Group>
        {description && <Badge variant="light">{description}</Badge>}
      </Group>

      <Divider mb="sm" />
      <Stack gap="sm">{children}</Stack>
    </Card>
  );
}

function FileInputWrapper({
  label,
  placeholder,
  accept,
  onChange,
  preview,
  name,
  description,
  required = false,
}: {
  label: string;
  placeholder?: string;
  accept?: string;
  onChange: (file: File | null) => void;
  preview?: string | null;
  name: string;
  description?: string;
  required?: boolean;
}) {
  return (
    <Stack gap="xs">
      <Flex direction={"column"}>
        <Group justify="apart" align="center">
          <Text fw={500}>
            {label}
            {required && (
              <Text span c="red" ml={4}>
                *
              </Text>
            )}
          </Text>
        </Group>
        {description && (
          <Text size="sm" c="dimmed" mt={4} style={{ lineHeight: 1.2 }}>
            {description}
          </Text>
        )}
      </Flex>

      <FileInput
        accept={accept}
        placeholder={placeholder}
        onChange={(f) => onChange(f)}
        leftSection={<IconUpload />}
        aria-label={label}
        name={name}
        clearable={true}
      />

      {preview ? (
        <div>
          <Text size="xs" color="dimmed">
            Preview:
          </Text>
          {/* If preview is an image it will show; pdf preview might not render as image */}
          {/* Use <object> or <img> depending on file type — keep simple here */}
          <div style={{ marginTop: 6 }}>
            <img
              src={preview}
              alt={`${label} preview`}
              style={{ maxWidth: "200px", borderRadius: 4 }}
            />
          </div>
        </div>
      ) : null}
    </Stack>
  );
}
