import { Button, Checkbox, CheckboxGroup, Input, Label, Picker, Text, Textarea, View } from "@tarojs/components";
import Taro, { useDidShow } from "@tarojs/taro";
import { useMemo, useState } from "react";
import { getJoinBranches, getMemberApplicationTemplate, getMyMemberApplication, saveMemberApplicationDraft, submitMemberApplication, supplementMemberApplication } from "../../api/member";
import { useAuthGuard } from "../../hooks/useAuthGuard";
import { firstText, resolveMediaUrl } from "../../utils/media";
import { uploadFileToBackend } from "../../utils/upload";
import { useActionDrawer } from "../../components/action-drawer";
import "./index.scss";

const EDITABLE_STATUSES = ["draft", "returned", "rejected", "branch_rejected", "city_rejected"];
const RESUBMIT_STATUSES = ["returned", "rejected", "branch_rejected", "city_rejected"];
const MATERIAL_EXTENSIONS = ["pdf", "docx", "jpg", "jpeg", "png", "webp"];
const GENDER_OPTIONS = ["男", "女", "其他"];
const TODAY_DATE_VALUE = new Date().toISOString().slice(0, 10);

function statusText(status?: string) {
  const map: Record<string, string> = {
    pending: "审核中",
    pending_city_review: "市级审核中",
    approved: "已通过",
    rejected: "已驳回，可重新提交",
    branch_rejected: "分会驳回，可重新提交",
    city_rejected: "市级驳回，可重新提交",
    returned: "已退回待补充",
    draft: "草稿"
  };
  return map[String(status || "")] || String(status || "");
}

function statusHint(status?: string) {
  if (status === "pending") return "资料已进入分会初审，请等待审核人员处理。";
  if (status === "pending_city_review") return "分会初审已通过，正在等待市级复审。";
  if (status === "approved") return "申请已通过，您已成为正式会员。";
  if (status === "returned") return "请按审核说明补充或修改材料后再次提交。";
  if (status === "rejected" || status === "branch_rejected" || status === "city_rejected") return "可根据审核说明修改资料后重新提交。";
  if (status === "draft") return "草稿尚未进入审核，请确认资料和材料完整后提交。";
  return "";
}

function scanDisplayName(scanFile: any) {
  return scanFile?.originalName || scanFile?.name || "已上传材料";
}

function uploadedFileId(file: any) {
  const id = Number(file?.fileId || file?.id || 0);
  return Number.isFinite(id) && id > 0 ? id : null;
}

function applicationFormData(application: any) {
  const raw = application?.formData || application?.form_data || application?.form_data_json || {};
  if (raw && typeof raw === "object") return raw;
  if (typeof raw !== "string" || !raw.trim()) return {};
  try {
    return JSON.parse(raw);
  } catch {
    return {};
  }
}

function fileNameFromPath(path?: string) {
  if (!path) return "";
  const normalized = path.replace(/\\/g, "/");
  return normalized.slice(normalized.lastIndexOf("/") + 1);
}

export default function JoinPage() {
  useAuthGuard();

  const [branches, setBranches] = useState<any[]>([]);
  const [myApplication, setMyApplication] = useState<any>(null);
  const [scanFile, setScanFile] = useState<any>(null);
  const [photoFile, setPhotoFile] = useState<any>(null);
  const [branchIds, setBranchIds] = useState<number[]>([]);
  const [submitting, setSubmitting] = useState(false);
  const [savingDraft, setSavingDraft] = useState(false);
  const [templateLoading, setTemplateLoading] = useState(false);
  const [error, setError] = useState("");
  const { showActionDrawer, actionDrawer } = useActionDrawer();
  const [form, setForm] = useState({
    realName: "",
    phone: "",
    category: "",
    unit: "",
    position: "",
    gender: "",
    birthMonth: "",
    nation: "",
    nativePlace: "",
    birthPlace: "",
    idCardNo: "",
    address: ""
  });

  const load = async () => {
    try {
      const [branchData, appData] = await Promise.all([getJoinBranches(), getMyMemberApplication()]);
      setBranches(Array.isArray(branchData) ? branchData : []);
      setMyApplication(appData && appData.id ? appData : null);
      if (appData?.id) {
        const formData = applicationFormData(appData);
        setForm((current) => ({
          ...current,
          realName: appData.realName || appData.real_name || current.realName,
          phone: appData.phone || current.phone,
          category: appData.category || current.category,
          unit: appData.unit || current.unit,
          position: appData.position || current.position,
          gender: formData.gender || current.gender,
          birthMonth: formData.birthDate || formData.birth_date || formData.birthMonth || formData.birth_month || current.birthMonth,
          nation: formData.nation || current.nation,
          nativePlace: formData.nativePlace || formData.native_place || current.nativePlace,
          birthPlace: formData.birthPlace || formData.birth_place || current.birthPlace,
          idCardNo: formData.identityDocumentNo || formData.identity_document_no || formData.idCardNo || formData.id_card_no || current.idCardNo,
          address: formData.address || current.address,
        }));
        const existingBranchIds = Array.isArray(appData.branchIds)
          ? appData.branchIds
          : Array.isArray(appData.branch_ids)
            ? appData.branch_ids
            : Array.isArray(appData.branches)
              ? appData.branches.map((branch: any) => branch.id)
              : [];
        setBranchIds(existingBranchIds.map((id: any) => Number(id)).filter(Boolean));
        const scanFileId = Number(appData.scanFileId || appData.scan_file_id || appData.scanFile?.id || 0);
        if (scanFileId) {
          setScanFile({
            fileId: scanFileId,
            originalName: appData.scanFileName || appData.scan_file_name || appData.scanFile?.name || "已上传材料",
          });
        } else {
          setScanFile(null);
        }
        const photoFileId = Number(formData.photoFileId || formData.photo_file_id || 0);
        if (photoFileId) {
          setPhotoFile({
            fileId: photoFileId,
            originalName: formData.photoFileName || formData.photo_file_name || "1寸照片",
          });
        } else {
          setPhotoFile(null);
        }
      } else {
        setScanFile(null);
        setPhotoFile(null);
        setBranchIds([]);
      }
      setError("");
    } catch (e: any) {
      setError(e?.message || "页面加载失败");
    }
  };

  useDidShow(() => {
    void load();
  });

  const applicationStatus = String(myApplication?.status || "");
  const canEdit = !applicationStatus || EDITABLE_STATUSES.includes(applicationStatus);
  const canResubmit = RESUBMIT_STATUSES.includes(applicationStatus);
  const rejectReason = myApplication?.rejectReason || myApplication?.reject_reason || "";
  const selectedBranchNames = useMemo(() => {
    const namesFromBranches = branches
      .filter((branch) => branchIds.includes(Number(branch.id)))
      .map((branch) => branch.name)
      .filter(Boolean);
    if (namesFromBranches.length > 0) return namesFromBranches;
    return Array.isArray(myApplication?.branches) ? myApplication.branches.map((branch: any) => branch?.name).filter(Boolean) : [];
  }, [branches, branchIds, myApplication]);
  const missingRequirements = useMemo(() => {
    if (!canEdit) return [];
    const missing: string[] = [];
    if (!form.realName.trim()) missing.push("姓名");
    if (!form.phone.trim()) missing.push("手机号");
    if (!form.category.trim()) missing.push("身份类别");
    if (!form.unit.trim()) missing.push("所在单位");
    if (!form.position.trim()) missing.push("职务");
    if (!uploadedFileId(scanFile)) missing.push("登记表材料");
    if (!uploadedFileId(photoFile)) missing.push("1寸照片");
    if (branchIds.length === 0) missing.push("申请分会");
    return missing;
  }, [canEdit, form.realName, form.phone, form.category, form.unit, form.position, scanFile, photoFile, branchIds]);
  const canSubmit = canEdit && missingRequirements.length === 0;

  const onPickScan = async () => {
    if (!canEdit) {
      Taro.showToast({ title: "当前状态不能修改材料", icon: "none" });
      return;
    }
    try {
      const action = await Taro.showActionSheet({ itemList: ["拍照或从相册选择", "从微信文件选择"] });
      let filePath = "";
      let originalName = "";
      if (action.tapIndex === 0) {
        const picked = await Taro.chooseImage({ count: 1, sizeType: ["compressed"], sourceType: ["album", "camera"] });
        filePath = picked?.tempFilePaths?.[0] || "";
        originalName = fileNameFromPath(filePath);
      } else {
        const picked = await Taro.chooseMessageFile({ count: 1, type: "file", extension: MATERIAL_EXTENSIONS });
        const file = picked?.tempFiles?.[0];
        filePath = file?.path || "";
        originalName = file?.name || fileNameFromPath(filePath);
      }
      if (!filePath) return;
      Taro.showLoading({ title: "上传中..." });
      const uploaded = await uploadFileToBackend(filePath, "member_application", { originalName });
      setScanFile(uploaded);
      Taro.hideLoading();
      Taro.showToast({ title: "材料已上传", icon: "none" });
    } catch (e: any) {
      Taro.hideLoading();
      const msg = e?.message || "上传失败";
      if (String(e?.errMsg || "").includes("cancel")) return;
      setError(msg);
      Taro.showToast({ title: msg, icon: "none" });
    }
  };

  const onPickPhoto = async () => {
    if (!canEdit) {
      Taro.showToast({ title: "当前状态不能修改照片", icon: "none" });
      return;
    }
    try {
      const picked = await Taro.chooseImage({ count: 1, sizeType: ["compressed"], sourceType: ["album", "camera"] });
      const filePath = picked?.tempFilePaths?.[0] || "";
      if (!filePath) return;
      Taro.showLoading({ title: "上传中..." });
      const originalName = fileNameFromPath(filePath);
      const uploaded = await uploadFileToBackend(filePath, "member_application_photo", originalName ? { originalName } : {});
      setPhotoFile(uploaded);
      Taro.hideLoading();
      Taro.showToast({ title: "照片已上传", icon: "none" });
    } catch (e: any) {
      Taro.hideLoading();
      const msg = e?.message || "照片上传失败";
      if (String(e?.errMsg || "").includes("cancel")) return;
      setError(msg);
      Taro.showToast({ title: msg, icon: "none" });
    }
  };

  const onDownloadTemplate = async () => {
    if (templateLoading) return;
    setTemplateLoading(true);
    try {
      const template = await getMemberApplicationTemplate();
      const configured = template?.configured === true || template?.configured === "true";
      const rawUrl = firstText(template?.downloadUrl, template?.download_url, template?.url, template?.publicUrl, template?.public_url);
      const url = resolveMediaUrl(rawUrl);
      if (!configured || !url) {
        Taro.showToast({ title: "模板暂未配置", icon: "none" });
        return;
      }
      Taro.showLoading({ title: "下载中..." });
      const result = await Taro.downloadFile({ url });
      Taro.hideLoading();
      if (result.statusCode && (result.statusCode < 200 || result.statusCode >= 300)) {
        throw new Error("下载失败");
      }
      await Taro.openDocument({
        filePath: result.tempFilePath,
        showMenu: true
      });
    } catch (e: any) {
      Taro.hideLoading();
      Taro.showToast({ title: e?.message || "模板下载失败", icon: "none" });
    } finally {
      setTemplateLoading(false);
    }
  };

  const buildPayload = () => ({
    realName: form.realName.trim(),
    phone: form.phone.trim(),
    unit: form.unit.trim(),
    position: form.position.trim(),
    category: form.category.trim(),
    branchIds,
    scanFileId: uploadedFileId(scanFile),
    formData: {
      gender: form.gender.trim(),
      birthDate: form.birthMonth.trim(),
      nation: form.nation.trim(),
      nativePlace: form.nativePlace.trim(),
      birthPlace: form.birthPlace.trim(),
      identityDocumentNo: form.idCardNo.trim(),
      address: form.address.trim(),
      photoFileId: uploadedFileId(photoFile),
      photoFileName: photoFile?.originalName || photoFile?.name || "1寸照片"
    }
  });

  const onSaveDraft = async () => {
    if (!canEdit || savingDraft || submitting) return;
    setSavingDraft(true);
    setError("");
    try {
      await saveMemberApplicationDraft(buildPayload());
      await showActionDrawer({
        type: "success",
        title: "草稿已保存",
        content: "草稿不会进入审核，资料完整后请继续提交。",
        confirmText: "知道了",
        showCancel: false
      });
      await load();
    } catch (e: any) {
      setError(e?.message || "草稿保存失败");
      Taro.showToast({ title: e?.message || "草稿保存失败", icon: "none" });
    } finally {
      setSavingDraft(false);
    }
  };

  const onSubmit = async () => {
    if (!canSubmit || submitting) return;
    setSubmitting(true);
    setError("");
    try {
      const payload = buildPayload();
      if (canResubmit) {
        await supplementMemberApplication(payload);
      } else {
        await submitMemberApplication(payload);
      }
      await showActionDrawer({
        type: "success",
        title: "成功提交",
        content: applicationStatus === "returned" ? "已补交，请等待审核" : canResubmit ? "已重新提交，请等待审核" : "请等待审核",
        confirmText: "知道了",
        showCancel: false
      });
      await load();
    } catch (e: any) {
      setError(e?.message || "提交失败");
      Taro.showToast({ title: e?.message || "提交失败", icon: "none" });
    } finally {
      setSubmitting(false);
    }
  };

  const approvedInfo = (() => {
    if (!myApplication || myApplication.status !== "approved") return "";
    const names = Array.isArray(myApplication.branches) ? myApplication.branches.map((b: any) => b?.name).filter(Boolean) : [];
    return names.length ? `，已是 ${names.join("、")} 会员` : "";
  })();
  const submitButtonText = applicationStatus === "returned"
    ? "补交申请"
    : canResubmit
      ? "重新提交申请"
      : "提交入会申请";

  return (
    <View className="page-shell join-page">
      <View className="page-body join-page__body">
        <View className="join-title">
          <Text className="join-title__main">
            大连市新的社会阶层专业人士联谊会
            {"\n"}
            会员登记表
          </Text>
        </View>

        {myApplication?.status ? (
          <View className="join-status">
            <Text className="join-status__text">
              我的申请状态：{statusText(applicationStatus)}
              {approvedInfo}
            </Text>
            {statusHint(applicationStatus) ? (
              <Text className="join-status__hint">{statusHint(applicationStatus)}</Text>
            ) : null}
            {rejectReason ? (
              <Text className="join-status__reason">
                审核说明：{rejectReason}
              </Text>
            ) : null}
          </View>
        ) : null}

        {!canEdit && myApplication?.status ? (
          <View className="join-readonly">
            <Text className="join-readonly__title">申请资料</Text>
            <View className="join-readonly__grid">
              <View className="join-readonly__item"><Text>姓名</Text><Text>{form.realName || "-"}</Text></View>
              <View className="join-readonly__item"><Text>手机号</Text><Text>{form.phone || "-"}</Text></View>
              <View className="join-readonly__item"><Text>身份类别</Text><Text>{form.category || "-"}</Text></View>
              <View className="join-readonly__item"><Text>所在单位</Text><Text>{form.unit || "-"}</Text></View>
              <View className="join-readonly__item"><Text>职务</Text><Text>{form.position || "-"}</Text></View>
              <View className="join-readonly__item"><Text>申请分会</Text><Text>{selectedBranchNames.join("、") || "-"}</Text></View>
              <View className="join-readonly__item is-wide"><Text>登记表材料</Text><Text>{scanFile ? scanDisplayName(scanFile) : "-"}</Text></View>
              <View className="join-readonly__item is-wide"><Text>1寸照片</Text><Text>{photoFile ? scanDisplayName(photoFile) : "-"}</Text></View>
              <View className="join-readonly__item"><Text>性别</Text><Text>{form.gender || "-"}</Text></View>
              <View className="join-readonly__item"><Text>出生日期</Text><Text>{form.birthMonth || "-"}</Text></View>
              <View className="join-readonly__item"><Text>民族</Text><Text>{form.nation || "-"}</Text></View>
              <View className="join-readonly__item"><Text>籍贯</Text><Text>{form.nativePlace || "-"}</Text></View>
              <View className="join-readonly__item"><Text>出生地</Text><Text>{form.birthPlace || "-"}</Text></View>
              <View className="join-readonly__item is-wide"><Text>身份证号/护照号</Text><Text>{form.idCardNo || "-"}</Text></View>
              <View className="join-readonly__item is-wide"><Text>通讯地址</Text><Text>{form.address || "-"}</Text></View>
            </View>
          </View>
        ) : (
          <>
            <View className="join-upload">
              <View className="join-section-head">
                <Text className="join-upload__title">会员登记表材料</Text>
                <Button className="join-template-button" loading={templateLoading} onClick={() => void onDownloadTemplate()}>
                  下载模板
                </Button>
              </View>
              <View className={`join-upload__box ${scanFile ? "is-filled" : ""}`} onClick={() => void onPickScan()}>
                <Text className="join-upload__plus">+</Text>
                <View className="join-upload__content">
                  <Text className="join-upload__label">{scanFile ? "重新上传材料" : "点击上传材料"}</Text>
                  <Text className="join-upload__file">{scanFile ? scanDisplayName(scanFile) : "支持 JPG / PNG / WEBP / PDF / DOCX"}</Text>
                </View>
              </View>
              <Text className={`join-upload__tip ${scanFile ? "is-success" : ""}`}>
                {scanFile ? `已上传：${scanDisplayName(scanFile)}` : "提交前必须先上传登记表材料"}
              </Text>
              <View className={`join-upload__box ${photoFile ? "is-filled" : ""}`} onClick={() => void onPickPhoto()}>
                <Text className="join-upload__plus">+</Text>
                <View className="join-upload__content">
                  <Text className="join-upload__label">{photoFile ? "重新上传1寸照片" : "点击上传1寸照片"}</Text>
                  <Text className="join-upload__file">{photoFile ? scanDisplayName(photoFile) : "支持 JPG / PNG / WEBP"}</Text>
                </View>
              </View>
              <Text className={`join-upload__tip ${photoFile ? "is-success" : ""}`}>
                {photoFile ? `已上传：${scanDisplayName(photoFile)}` : "提交前必须上传1寸照片"}
              </Text>
            </View>

            <View className="join-form">
              <View className="join-form__grid">
                <Input className="join-input" value={form.realName} onInput={(e) => setForm((s) => ({ ...s, realName: e.detail.value }))} placeholder="姓名" />
                <Input className="join-input" value={form.category} onInput={(e) => setForm((s) => ({ ...s, category: e.detail.value }))} placeholder="身份类别" />
                <Picker mode="selector" range={GENDER_OPTIONS} value={Math.max(0, GENDER_OPTIONS.indexOf(form.gender))} onChange={(e) => setForm((s) => ({ ...s, gender: GENDER_OPTIONS[Number(e.detail.value)] || "" }))}>
                  <View className={`join-input join-picker ${form.gender ? "" : "is-placeholder"}`}>
                    <Text>{form.gender || "性别"}</Text>
                  </View>
                </Picker>
                <Picker mode="date" start="1900-01-01" end={TODAY_DATE_VALUE} value={form.birthMonth || "1990-01-01"} onChange={(e) => setForm((s) => ({ ...s, birthMonth: String(e.detail.value || "") }))}>
                  <View className={`join-input join-picker ${form.birthMonth ? "" : "is-placeholder"}`}>
                    <Text>{form.birthMonth || "出生日期"}</Text>
                  </View>
                </Picker>
                <Input className="join-input" value={form.nation} onInput={(e) => setForm((s) => ({ ...s, nation: e.detail.value }))} placeholder="民族" />
                <Input className="join-input" value={form.nativePlace} onInput={(e) => setForm((s) => ({ ...s, nativePlace: e.detail.value }))} placeholder="籍贯" />
                <Input className="join-input" value={form.birthPlace} onInput={(e) => setForm((s) => ({ ...s, birthPlace: e.detail.value }))} placeholder="出生地" />
                <Input className="join-input" value={form.phone} onInput={(e) => setForm((s) => ({ ...s, phone: e.detail.value }))} placeholder="手机号" />
                <Input className="join-input" value={form.idCardNo} onInput={(e) => setForm((s) => ({ ...s, idCardNo: e.detail.value }))} placeholder="身份证号/护照号" />
                <Input className="join-input" value={form.unit} onInput={(e) => setForm((s) => ({ ...s, unit: e.detail.value }))} placeholder="所在单位" />
                <Input className="join-input join-input--wide" value={form.position} onInput={(e) => setForm((s) => ({ ...s, position: e.detail.value }))} placeholder="职务" />
              </View>
              <Textarea className="join-textarea" value={form.address} onInput={(e) => setForm((s) => ({ ...s, address: e.detail.value }))} placeholder="通讯地址" autoHeight />
            </View>

            <View className="join-branches">
              <Text className="join-branches__title">选择加入分会（可多选）</Text>
              <CheckboxGroup className="join-branches__list" onChange={(e) => setBranchIds((e.detail.value || []).map((v) => Number(v)))}>
                {branches.map((branch) => (
                  <Label key={branch.id} className={`join-branches__item ${branchIds.includes(Number(branch.id)) ? "is-checked" : ""}`}>
                    <Checkbox className="join-branches__checkbox" value={String(branch.id)} checked={branchIds.includes(Number(branch.id))} />
                    <View className="join-branches__copy">
                      <Text className="join-branches__name">{branch.name}</Text>
                      <Text className="join-branches__hint">选择后提交至该分会审核</Text>
                    </View>
                  </Label>
                ))}
              </CheckboxGroup>
            </View>

            {error ? (
              <View className="join-error">
                <Text>{error}</Text>
              </View>
            ) : null}

            <View className="join-submit">
              {missingRequirements.length > 0 ? (
                <Text className="join-submit__tip">还需填写：{missingRequirements.join("、")}</Text>
              ) : null}
              <Button className="join-submit__draft" disabled={!canEdit || savingDraft || submitting} loading={savingDraft} onClick={() => void onSaveDraft()}>
                保存草稿
              </Button>
              <Button className="join-submit__button" disabled={!canSubmit || submitting} loading={submitting} onClick={() => void onSubmit()}>
                {submitButtonText}
              </Button>
            </View>
          </>
        )}
      </View>
      {actionDrawer}
    </View>
  );
}
