import { Button, Image, Input, Text, Textarea, View } from "@tarojs/components";
import Taro from "@tarojs/taro";
import { useMemo, useState } from "react";
import {
  REPAIR_DESCRIPTION_LIMIT,
  REPAIR_DEVICE_TYPE_LABELS,
  REPAIR_DRAFT_STORAGE_KEY,
  type RepairAttachment,
  type RepairDeviceOption,
  type RepairDeviceType,
  type RepairSubmissionSnapshot,
  appendRepairAttachments,
  buildDeviceMap,
  clampDescription,
  normalizeChosenFiles,
  validateRepairForm
} from "./repair-utils";
import "./index.scss";

const repairDevices: RepairDeviceOption[] = [
  { id: "A9876456546", type: "monitor", label: "A9876456546", params: "3AW1 / 654616313" },
  { id: "A3648201488", type: "monitor", label: "A3648201488", params: "5BZ2 / 882730114" },
  { id: "C7842037781", type: "camera", label: "C7842037781", params: "AI-CAM / 220184900" },
  { id: "C7842037782", type: "camera", label: "C7842037782", params: "AI-CAM / 220184901" }
];

const groupedDevices = buildDeviceMap(repairDevices);
const deviceTypeOrder: RepairDeviceType[] = ["monitor", "camera"];

function delay(ms: number) {
  return new Promise((resolve) => {
    setTimeout(resolve, ms);
  });
}

function formatAttachmentSize(size?: number) {
  if (!size) {
    return "";
  }

  if (size >= 1024 * 1024) {
    return `${(size / 1024 / 1024).toFixed(1)}MB`;
  }

  return `${Math.max(size / 1024, 0.1).toFixed(1)}KB`;
}

function createTicketNo() {
  return `BX${Date.now().toString().slice(-8)}`;
}

export default function RepairPage() {
  const [deviceType, setDeviceType] = useState<RepairDeviceType>("monitor");
  const [selectedDeviceId, setSelectedDeviceId] = useState(groupedDevices.monitor[0]?.id || "");
  const [description, setDescription] = useState("");
  const [attachments, setAttachments] = useState<RepairAttachment[]>([]);
  const [contactName, setContactName] = useState("张小龙");
  const [phone, setPhone] = useState("13689569989");
  const [submitting, setSubmitting] = useState(false);

  const currentDevices = groupedDevices[deviceType];
  const selectedDevice =
    currentDevices.find((item) => item.id === selectedDeviceId) || currentDevices[0] || repairDevices[0];
  const imageCount = attachments.filter((item) => item.kind === "image").length;
  const videoCount = attachments.filter((item) => item.kind === "video").length;
  const uploadHint = useMemo(() => {
    if (deviceType === "camera") {
      return "点击上传AI摄像头故障照片或视频";
    }

    return "点击上传体征设备故障照片或视频";
  }, [deviceType]);

  const showToast = (title: string) => {
    Taro.showToast({
      title,
      icon: "none"
    });
  };

  const handleTypeChange = (nextType: RepairDeviceType) => {
    if (nextType === deviceType) {
      return;
    }

    const nextDevices = groupedDevices[nextType];
    setDeviceType(nextType);
    setSelectedDeviceId(nextDevices[0]?.id || "");
  };

  const handleSelectDevice = async () => {
    if (!currentDevices.length) {
      showToast("当前暂无可选设备");
      return;
    }

    try {
      const result = await Taro.showActionSheet({
        itemList: currentDevices.map((item) => item.label)
      });

      const nextDevice = currentDevices[result.tapIndex];

      if (nextDevice) {
        setSelectedDeviceId(nextDevice.id);
      }
    } catch (error) {
      const message = error instanceof Error ? error.message : "";

      if (!message.includes("cancel")) {
        showToast("设备选择失败");
      }
    }
  };

  const handleChooseMedia = async () => {
    try {
      const result = await Taro.chooseMedia({
        count: 9,
        mediaType: ["image", "video"],
        sourceType: ["album", "camera"]
      });

      const chosen = normalizeChosenFiles((result.tempFiles || []) as never[]);

      if (!chosen.length) {
        return;
      }

      const merged = appendRepairAttachments(attachments, chosen);
      setAttachments(merged.attachments);

      if (merged.errorMessage) {
        showToast(merged.errorMessage);
      }
    } catch (error) {
      const message = error instanceof Error ? error.message : "";

      if (message.includes("cancel")) {
        return;
      }

      showToast("上传失败，请重试");
    }
  };

  const handlePreviewAttachment = (attachment: RepairAttachment) => {
    if (attachment.kind === "image") {
      Taro.previewImage({
        current: attachment.path,
        urls: attachments.filter((item) => item.kind === "image").map((item) => item.path)
      });
      return;
    }

    const previewMedia = (Taro as unknown as {
      previewMedia?: (options: {
        current?: number;
        sources: Array<{ url: string; type: "image" | "video"; poster?: string }>;
      }) => Promise<unknown>;
    }).previewMedia;

    if (typeof previewMedia === "function") {
      void previewMedia({
        current: 0,
        sources: [
          {
            url: attachment.path,
            type: "video",
            poster: attachment.thumbPath
          }
        ]
      });
      return;
    }

    showToast("当前环境暂不支持视频预览");
  };

  const handleDeleteAttachment = (attachmentId: string, event: { stopPropagation?: () => void }) => {
    event.stopPropagation?.();
    setAttachments((prev) => prev.filter((item) => item.id !== attachmentId));
  };

  const handleSubmit = async () => {
    const errorMessage = validateRepairForm({
      selectedDeviceId,
      description,
      contactName,
      phone
    });

    if (errorMessage) {
      showToast(errorMessage);
      return;
    }

    if (!selectedDevice) {
      showToast("请选择设备");
      return;
    }

    const payload: RepairSubmissionSnapshot = {
      ticketNo: createTicketNo(),
      deviceType,
      deviceTypeLabel: REPAIR_DEVICE_TYPE_LABELS[deviceType],
      deviceId: selectedDevice.id,
      deviceParams: selectedDevice.params,
      description: description.trim(),
      attachments,
      contactName: contactName.trim(),
      phone: phone.trim(),
      createdAt: new Date().toLocaleString("zh-CN", { hour12: false }),
      statusLabel: "已提交，待审核"
    };

    setSubmitting(true);

    try {
      await delay(800);
      Taro.setStorageSync(REPAIR_DRAFT_STORAGE_KEY, payload);
      await Taro.showToast({
        title: "提交成功",
        icon: "success"
      });
      await Taro.navigateTo({ url: "/pages/repair-detail/index" });
    } catch {
      showToast("提交失败，请稍后重试");
    } finally {
      setSubmitting(false);
    }
  };

  return (
    <View className="repair-page">
      <View className="repair-page__glow repair-page__glow--left" />
      <View className="repair-page__glow repair-page__glow--right" />

      <View className="repair-page__toolbar">
        <View className="repair-page__toolbar-spacer" />

        <View className="repair-page__history" onClick={() => showToast("历史记录功能待开放")}>
          <View className="repair-page__clock">
            <View className="repair-page__clock-hand repair-page__clock-hand--hour" />
            <View className="repair-page__clock-hand repair-page__clock-hand--minute" />
          </View>
          <Text className="repair-page__history-text">历史记录</Text>
        </View>
      </View>

      <View className="repair-page__tabs">
        {deviceTypeOrder.map((item) => (
          <View
            className={`repair-page__tab ${item === deviceType ? "repair-page__tab--active" : ""}`}
            key={item}
            onClick={() => handleTypeChange(item)}
          >
            <Text className={`repair-page__tab-text ${item === deviceType ? "repair-page__tab-text--active" : ""}`}>
              {REPAIR_DEVICE_TYPE_LABELS[item]}
            </Text>
          </View>
        ))}
      </View>

      <View className="repair-page__card">
        <View className="repair-page__field-row">
          <Text className="repair-page__field-label">设备ID</Text>
          <View className="repair-page__field-box repair-page__field-box--select" onClick={handleSelectDevice}>
            <Text className="repair-page__field-value">{selectedDevice?.label || "请选择设备"}</Text>
            <View className="repair-page__chevron" />
          </View>
        </View>

        <View className="repair-page__field-row">
          <Text className="repair-page__field-label">设备参数</Text>
          <View className="repair-page__field-box repair-page__field-box--disabled">
            <Text className="repair-page__field-value repair-page__field-value--muted">{selectedDevice?.params || "--"}</Text>
          </View>
        </View>

        <View className="repair-page__textarea-wrap">
          <Textarea
            className="repair-page__textarea"
            maxlength={REPAIR_DESCRIPTION_LIMIT}
            placeholder="问题描述（60个字以内）"
            placeholderClass="repair-page__placeholder"
            value={description}
            onInput={(event) => setDescription(clampDescription(event.detail.value))}
          />
          <Text className="repair-page__textarea-count">
            {description.length}/{REPAIR_DESCRIPTION_LIMIT}
          </Text>
        </View>

        <View className="repair-page__upload-panel" onClick={handleChooseMedia}>
          <View className="repair-page__camera">
            <View className="repair-page__camera-top" />
            <View className="repair-page__camera-body">
              <View className="repair-page__camera-lens" />
            </View>
          </View>
          <Text className="repair-page__upload-title">{uploadHint}</Text>
          <Text className="repair-page__upload-subtitle">
            图片 {imageCount}/9，视频 {videoCount}/1
          </Text>
        </View>

        {attachments.length ? (
          <View className="repair-page__attachment-grid">
            {attachments.map((attachment) => (
              <View
                className={`repair-page__attachment ${attachment.kind === "video" ? "repair-page__attachment--video" : ""}`}
                key={attachment.id}
                onClick={() => handlePreviewAttachment(attachment)}
              >
                {attachment.kind === "image" ? (
                  <Image className="repair-page__attachment-image" mode="aspectFill" src={attachment.path} />
                ) : (
                  <View className="repair-page__video-cover">
                    {attachment.thumbPath ? (
                      <Image className="repair-page__attachment-image" mode="aspectFill" src={attachment.thumbPath} />
                    ) : null}
                    <View className="repair-page__video-badge">VIDEO</View>
                  </View>
                )}

                <View className="repair-page__attachment-meta">
                  <Text className="repair-page__attachment-name">{attachment.name || "附件"}</Text>
                  <Text className="repair-page__attachment-size">
                    {attachment.kind === "video" ? `视频 ${formatAttachmentSize(attachment.size)}` : formatAttachmentSize(attachment.size)}
                  </Text>
                </View>

                <View className="repair-page__attachment-delete" onClick={(event) => handleDeleteAttachment(attachment.id, event)}>
                  <Text className="repair-page__attachment-delete-text">×</Text>
                </View>
              </View>
            ))}
          </View>
        ) : null}
      </View>

      <View className="repair-page__add-card" onClick={handleChooseMedia}>
        <View className="repair-page__plus">
          <View className="repair-page__plus-line repair-page__plus-line--horizontal" />
          <View className="repair-page__plus-line repair-page__plus-line--vertical" />
        </View>
        <Text className="repair-page__add-text">继续添加附件</Text>
      </View>

      <View className="repair-page__card repair-page__card--contact">
        <View className="repair-page__field-row">
          <Text className="repair-page__field-label">联系人</Text>
          <View className="repair-page__field-box">
            <Input
              className="repair-page__input"
              maxlength={20}
              placeholder="请输入联系人"
              placeholderClass="repair-page__placeholder"
              value={contactName}
              onInput={(event) => setContactName(event.detail.value)}
            />
          </View>
        </View>

        <View className="repair-page__field-row">
          <Text className="repair-page__field-label">手机号</Text>
          <View className="repair-page__field-box">
            <Input
              className="repair-page__input"
              maxlength={11}
              placeholder="请输入手机号"
              placeholderClass="repair-page__placeholder"
              type="number"
              value={phone}
              onInput={(event) => setPhone(event.detail.value)}
            />
          </View>
        </View>
      </View>

      <Button className="repair-page__submit" disabled={submitting} loading={submitting} onClick={handleSubmit}>
        提交
      </Button>
    </View>
  );
}
