import React, { useState, useRef } from "react";
import { View, Text, Button, Image } from "@tarojs/components";
import { Dialog } from "@nutui/nutui-react-taro";
import Taro, { useDidShow, useRouter } from "@tarojs/taro";
import dayjs from "dayjs";
import "dayjs/locale/zh-cn";
import classnames from "classnames";
import orderService, {
  CancelType,
  GameOrderRes,
  OrderStatus,
  RefundStatus,
} from "@/services/orderService";
import {
  payOrder,
  delay,
  calculateDistance,
  getCurrentLocation,
  getOrderStatus,
  generateOrderActions,
} from "@/utils";
import detailService, { GameData } from "@/services/detailService";
import { withAuth, RefundPopup } from "@/components";
import img from "@/config/images";
import { DECLAIMER } from "./config";
import styles from "./index.module.scss";

dayjs.locale("zh-cn");

const refundTextMap = new Map([
  [RefundStatus.NONE, "已支付"],
  [RefundStatus.PENDING, "退款中"],
  [RefundStatus.SUCCESS, "已退款"],
]);

const gameNoticeMap = new Map([
  [
    "pending",
    { title: "球局暂未开始", content: "球局开始前2小时，我们将通过短信通知你" },
  ],
  [
    "pendinging",
    {
      title: "球局即将开始，请按时抵达球局",
      content: "球局开始前2小时，我们将通过短信通知你",
    },
  ],
  ["progress", { title: "球局已开始", content: "友谊第一，比赛第二" }],
  ["finish", { title: "球局已结束", content: "" }],
]);

function genGameNotice(order_status, start_time) {
  const startTime = dayjs(start_time);
  let key = "";
  if (order_status === OrderStatus.FINISHED) {
    key = "finish";
  }
  const leftHour = startTime.diff(dayjs(), "hour");
  const start = startTime.isBefore(dayjs());
  if (start) {
    key = "progress";
  } else if (leftHour > 2) {
    key = "pending";
  } else if (leftHour < 2) {
    key = "pendinging";
  }

  return gameNoticeMap.get(key) || {};
}

function GameInfo(props) {
  const { detail, currentLocation, orderDetail, init } = props;
  // console.log(orderDetail, "orderDetail");
  const { order_status, refund_status } = orderDetail;
  const { latitude, longitude, location, location_name, start_time, end_time, weather } =
    detail || {};

  const [{ iconDay, tempMax, tempMin }] = weather || [{}];

  const refundRef = useRef(null);

  const openMap = () => {
    Taro.openLocation({
      latitude, // 纬度（必填）
      longitude, // 经度（必填）
      name: location_name, // 位置名（可选）
      address: location, // 地址详情（可选）
      scale: 15, // 地图缩放级别（1-28）
    });
  };

  const [c_latitude, c_longitude] = currentLocation;
  const distance =
    c_latitude + c_longitude === 0
      ? 0
      : calculateDistance(c_latitude, c_longitude, latitude, longitude) / 1000;

  const startTime = dayjs(start_time);
  const endTime = dayjs(end_time);
  const game_length = endTime.diff(startTime, "minutes") / 60;

  const startMonth = startTime.format("M");
  const startDay = startTime.format("D");
  const theDayOfWeek = startTime.format("dddd");
  const startDate = `${startMonth}月${startDay}日 ${theDayOfWeek}`;
  const gameRange = `${startTime.format("HH:mm")} - ${endTime.format("HH:mm")}`;

  const orderStatus = getOrderStatus(orderDetail);

  const gameNotice = genGameNotice(order_status, start_time);

  function handleViewGame(gameId) {
    Taro.navigateTo({
      url: `/game_pages/detail/index?id=${gameId}&from=orderList`,
    });
  }

  async function handleDeleteOrder(item) {
    const { order_id } = item;
    const onCancel = () => {
      Dialog.close("detailCancelOrder");
    };
    const onConfirm = async () => {
      try {
        const deleteRes = await orderService.deleteOrder({
          order_id,
        });
        if (deleteRes.code !== 0) {
          throw new Error(deleteRes.message);
        }
        Taro.showToast({
          title: "删除成功",
          icon: "none",
        });
        delay(2000);
        Taro.redirectTo({ url: "/order_pages/orderList/index" });
      } catch (e) {
        Taro.showToast({
          title: e.message,
          icon: "error",
        });
      } finally {
        Dialog.close("detailCancelOrder");
      }
    };
    Dialog.open("detailCancelOrder", {
      title: "确定删除订单吗？",
      content: (
        <View className={styles.cancelTip}>
          <Text>删除订单后，您将无法恢复订单。请确认是否继续取消？</Text>
        </View>
      ),
      footer: (
        <View className={styles.dialogFooter}>
          <Button className={styles.cancel} onClick={onCancel}>
            取消
          </Button>
          <Button className={styles.confirm} type="primary" onClick={onConfirm}>
            确认
          </Button>
        </View>
      ),
      onConfirm,
      onCancel,
    });
  }

  async function handleCancelOrder(item) {
    const { order_no } = item;
    const onCancel = () => {
      Dialog.close("detailCancelOrder");
    };
    const onConfirm = async () => {
      try {
        const cancelRes = await orderService.cancelUnpaidOrder({
          order_no,
          cancel_reason: "用户主动取消",
        });
        if (cancelRes.code !== 0) {
          throw new Error(cancelRes.message);
        }
        init();
        Taro.showToast({
          title: "取消成功",
          icon: "none",
        });
      } catch (e) {
        Taro.showToast({
          title: e.message,
          icon: "error",
        });
      } finally {
        Dialog.close("detailCancelOrder");
      }
    };
    Dialog.open("detailCancelOrder", {
      title: "确定取消订单吗？",
      content: (
        <View className={styles.cancelTip}>
          <Text>取消订单后，您将无法恢复订单。请确认是否继续取消？</Text>
        </View>
      ),
      footer: (
        <View className={styles.dialogFooter}>
          <Button className={styles.cancel} onClick={onCancel}>
            取消
          </Button>
          <Button className={styles.confirm} type="primary" onClick={onConfirm}>
            确认
          </Button>
        </View>
      ),
      onConfirm,
      onCancel,
    });
  }

  function handleQuit(item) {
    if (refundRef.current) {
      refundRef.current.show(item, (result) => {
        if (result) {
          init();
        }
      });
    }
  }

  return (
    <View className={styles.gameInfoContainer}>
      {["progress", "expired"].includes(orderStatus) && (
        <>
          <View className={styles.paidInfo}>
            {refundTextMap.get(refund_status)} ¥ 90
          </View>
          <View className={styles.gameStatus}>
            <Text className={styles.statusText}>{gameNotice.title}</Text>
            {gameNotice.content && <Text>{gameNotice.content}</Text>}
          </View>
        </>
      )}
      <View className={styles.gameInfo}>
        {/* Date and Weather */}
        <View className={styles.gameInfoDateWeather}>
          {/* Calendar and Date time */}
          <View className={styles.gameInfoDateWeatherCalendarDate}>
            {/* Calendar */}
            <View className={styles.gameInfoDateWeatherCalendarDateCalendar}>
              <View className={styles.month}>{startMonth}月</View>
              <View className={styles.day}>{startDay}</View>
            </View>
            {/* Date time */}
            <View className={styles.gameInfoDateWeatherCalendarDateDate}>
              <View className={styles.date}>{startDate}</View>
              <View className={styles.venueTime}>
                {gameRange} （{game_length}小时）
              </View>
            </View>
          </View>
          <View className={styles.weather}>
            {/* Weather icon */}
            <View className={styles.weatherIcon}>
              {/*<Image className="weather-icon" src={img.ICON_WEATHER_SUN} />*/}
              <i className={`qi-${iconDay}`}></i>
            </View>
            {/* Weather text and temperature */}
            <View className={styles.temperature}>
              {tempMin && tempMax && (
                <Text>
                  {tempMin}℃ - {tempMax}℃
                </Text>
              )}
            </View>
          </View>
        </View>
        {/* Place */}
        <View className={styles.gameInfoPlace}>
          {/* venue location message */}
          <View className={styles.locationMessage}>
            {/* location icon */}
            <View className={styles.locationMessageIcon}>
              <Image
                className={styles.locationMessageIconImage}
                src="https://bimwe.oss-cn-shanghai.aliyuncs.com/front/ball/images/43aab7e9-061e-4e3b-88c6-61c19b660b22.png"
              />
            </View>
            {/* location message */}
            <View className={styles.locationMessageText}>
              {/* venue name and distance */}
              <View
                className={styles.locationMessageTextNameDistance}
                onClick={openMap}
              >
                <Text>{location_name || "-"}</Text>
                {distance ? (
                  <>
                    <Text>·</Text>
                    <Text>{distance.toFixed(1)}km</Text>
                  </>
                ) : null}

                <Image
                  className={styles.locationMessageTextNameDistanceArrow}
                  src={img.ICON_DETAIL_ARROW_RIGHT}
                />
              </View>
              {/* venue address */}
              <View className={styles.locationMessageTextAddress}>
                <Text>{location || "-"}</Text>
              </View>
            </View>
          </View>
        </View>
      </View>
      {/* Action bar */}
      <View className={styles.gameInfoActions}>
        {orderDetail.order_id
          ? generateOrderActions(
              orderDetail,
              {
                handleDeleteOrder,
                handleCancelOrder,
                handleQuit,
                handlePayNow: () => {},
                handleViewGame,
              },
              "detail"
            )?.map((obj) => (
              <Button
                className={classnames(styles.button, styles[obj.className])}
                onClick={obj.action}
              >
                {obj.text}
              </Button>
            ))
          : ""}
      </View>
      <Dialog id="detailCancelOrder" />
      <RefundPopup ref={refundRef} />
    </View>
  );
}

function handleCopy(msg) {
  Taro.setClipboardData({
    data: msg,
  });
}

function OrderMsg(props) {
  const { detail, orderDetail, checkOrderInfo } = props;
  const {
    start_time,
    end_time,
    location,
    location_name,
    wechat_contact,
    price,
  } = detail;
  const { order_no } = orderDetail;
  const { order_info: { registrant_phone } = {} } = checkOrderInfo;
  const startTime = dayjs(start_time);
  const endTime = dayjs(end_time);
  const startYear = startTime.format("YYYY");
  const startMonth = startTime.format("M");
  const startDay = startTime.format("D");
  const startDate = `${startYear}年${startMonth}月${startDay}日`;
  const gameRange = `${startTime.format("HH:mm")} - ${endTime.format("HH:mm")}`;
  const summary = [
    {
      title: "时间",
      content: `${startDate} ${gameRange}`,
    },
    {
      title: "地址",
      content: (
        <View className={styles.location}>
          <Text>{location}</Text>
          <Text>{location_name}</Text>
        </View>
      ),
    },
    {
      title: "报名人电话",
      content: registrant_phone,
    },
    {
      title: "组织人微信号",
      content: wechat_contact,
    },
    {
      title: "组织人电话",
      content: wechat_contact,
    },
    {
      title: "费用",
      content: `${price} 元 / 人`,
    },
    ...(order_no
      ? [
          {
            title: "订单号",
            content: (
              <View className={styles.orderNo}>
                <Text>{order_no}</Text>
                <Text
                  className={styles.copy}
                  onClick={handleCopy.bind(null, order_no)}
                >
                  复制
                </Text>
              </View>
            ),
          },
        ]
      : []),
  ];
  return (
    <View className={styles.orderSummary}>
      <View className={styles.moduleTitle}>
        <Text>确认订单信息</Text>
      </View>
      {/* 订单信息摘要 */}
      <View className={styles.summaryList}>
        {summary.map((item, index) => (
          <View key={index} className={styles.summaryItem}>
            <Text className={styles.title}>{item.title}</Text>
            <View className={styles.content}>{item.content}</View>
          </View>
        ))}
      </View>
    </View>
  );
}

function RefundPolicy(props) {
  const { checkOrderInfo } = props;
  const { refund_policy = [] } = checkOrderInfo;
  const policyList = [
    {
      time: "申请退款时间",
      rule: "退款规则",
    },
    ...refund_policy.map((item, index) => {
      const isLast = index === refund_policy.length - 1;
      const theTimeObj = dayjs(
        isLast
          ? refund_policy.at(-2).deadline_formatted
          : item.deadline_formatted
      );
      const year = theTimeObj.format("YYYY");
      const month = theTimeObj.format("M");
      const day = theTimeObj.format("D");
      const time = theTimeObj.format("HH:mm");
      return {
        time: `${year}年${month}月${day}日${time} ${isLast ? "后" : "前"}`,
        rule: item.refund_rule,
      };
    }),
  ];
  return (
    <View className={styles.refundPolicy}>
      <View className={styles.moduleTitle}>
        <Text>退款政策</Text>
      </View>
      {/* 订单信息摘要 */}
      <View className={styles.policyList}>
        {policyList.map((item, index) => (
          <View key={index} className={styles.policyItem}>
            <View className={styles.time}>{item.time}</View>
            <View className={styles.rule}>{item.rule}</View>
          </View>
        ))}
      </View>
    </View>
  );
}

function Disclaimer() {
  return (
    <View className={styles.declaimer}>
      <Text className={styles.title}>免责声明</Text>
      <Text className={styles.content}>{DECLAIMER}</Text>
    </View>
  );
}

const OrderCheck = () => {
  const { params } = useRouter();
  const { id: stringId, gameId: stringGameId } = params;
  const [id, gameId] = [Number(stringId), Number(stringGameId)];
  const [detail, setDetail] = useState<GameData | {}>({});
  const [location, setLocation] = useState<number[]>([0, 0]);
  const [checkOrderInfo, setCheckOrderInfo] = useState<GameOrderRes | {}>({});
  const [orderDetail, setOrderDetail] = useState({});

  useDidShow(() => {
    init()
  });

  async function init() {
    let gameDetail = {};
    if (id) {
      const res = await orderService.getOrderDetail(id);
      if (res.code === 0) {
        setOrderDetail(res.data);
        gameDetail = res.data.game_info;
      }
    } else if (gameId) {
      const res = await detailService.getDetail(gameId);
      if (res.code === 0) {
        gameDetail = res.data;
      }
    }
    if (gameDetail.id) {
      setDetail(gameDetail);
      onInit(gameDetail.id);
    }
  }

  async function checkOrder(gid) {
    const orderRes = await orderService.getCheckOrderInfo(gid);
    setCheckOrderInfo(orderRes.data);
  }

  async function onInit(gid) {
    checkOrder(gid);
    const location = await getCurrentLocation();
    setLocation([location.latitude, location.longitude]);
  }

  async function getPaymentParams() {
    const unPaidRes = await orderService.getUnpaidOrder(detail.id);
    if (unPaidRes.code === 0 && unPaidRes.data.has_unpaid_order) {
      return unPaidRes.data.payment_params;
    }
    const createOrderRes = await orderService.createOrder(detail.id);
    if (createOrderRes.code === 0) {
      return createOrderRes.data.payment_params;
    }
    throw new Error("支付调用失败");
  }

  //TODO: get order msg from id
  const handlePay = async () => {
    Taro.showLoading({
      title: "支付中...",
      mask: true,
    });

    let payment_params = {}
    try {
      payment_params = await getPaymentParams();
      await payOrder(payment_params);
      Taro.hideLoading();
      Taro.showToast({
        title: "支付成功",
        icon: "success",
      });
      // Taro.navigateBack({
      //   delta: 1,
      // });
    } catch (error) {
      Taro.hideLoading();
      Taro.showToast({
        title: error.message,
        icon: "none",
      });
    } finally {
      await delay(1000);
      if (!id) {
        Taro.redirectTo({
          url: `/order_pages/orderDetail/index?id=${payment_params.order_id}`,
        });
      } else {
        init()
      }
    }
  };
  if (!id && !gameId) {
    return (
      <View className={styles.errorTip}>
        <Text>异常订单</Text>
        <Button
          type="warn"
          onClick={() => {
            Taro.redirectTo({ url: "/game_pages/list/index" });
          }}
        >
          回到首页
        </Button>
      </View>
    );
  }

  const { order_status, cancel_type } = orderDetail;

  return (
    <View className={styles.container}>
      {/* Game Date and Address */}
      <GameInfo
        detail={detail}
        orderDetail={orderDetail}
        currentLocation={location}
        init={init}
      />
      {/* Order message */}
      <OrderMsg
        detail={detail}
        orderDetail={orderDetail}
        checkOrderInfo={checkOrderInfo}
      />
      {/* Refund policy */}
      <RefundPolicy checkOrderInfo={checkOrderInfo} />
      {/* Disclaimer */}
      <Disclaimer />
      {(!id ||
        (order_status === OrderStatus.PENDING &&
          cancel_type === CancelType.NONE)) && (
        <Button className={styles.payButton} onClick={handlePay}>
          {order_status === OrderStatus.PENDING ? "继续" : "确认"}
          支付
        </Button>
      )}
    </View>
  );
};

export default withAuth(OrderCheck);
