'use client'

import {use, useEffect, useRef, useState} from 'react'
import Link from 'next/link'
import {useFormContext, useWatch} from 'react-hook-form'
import {Card} from '@/components/ui/card'
import {buttonVariants} from '@/components/ui/button'
import {useProfileStore} from '@/components/stores/profile'
import Pay from '@/components/composites/purchase/pay'
import {FieldPayment} from './field-payment'
import {buildPurchaseResource, PurchaseKind, PurchaseSelection} from './resource'
import {getPrice, getPriceHome} from '@/actions/resource'
import {ExtraResp} from '@/lib/api'
import {formatPurchaseLiveLabel} from './sku'
import {User} from '@/lib/models'
import {PurchaseFormValues} from './form-values'
import {IdCard} from 'lucide-react'

const emptyPrice: ExtraResp<typeof getPrice> = {
  price: '0.00',
  actual: '0.00',
  discounted: '0.00',
}

export type PurchaseSidePanelProps = {
  kind: PurchaseKind
}

export function PurchaseSidePanel(props: PurchaseSidePanelProps) {
  const {control} = useFormContext<PurchaseFormValues>()
  const method = useWatch<PurchaseFormValues>({control, name: 'pay_type'}) as PurchaseFormValues['pay_type']
  const mode = useWatch<PurchaseFormValues>({control, name: 'type'}) as PurchaseFormValues['type']
  const live = useWatch<PurchaseFormValues>({control, name: 'live'}) as PurchaseFormValues['live']
  const quota = useWatch<PurchaseFormValues>({control, name: 'quota'}) as PurchaseFormValues['quota']
  const expire = useWatch<PurchaseFormValues>({control, name: 'expire'}) as PurchaseFormValues['expire']
  const dailyLimit = useWatch<PurchaseFormValues>({control, name: 'daily_limit'}) as PurchaseFormValues['daily_limit']
  const profile = use(useProfileStore(store => store.profile))
  const selection: PurchaseSelection = {
    kind: props.kind,
    mode,
    live,
    quota,
    expire,
    dailyLimit,
  }
  const priceData = usePurchasePrice(profile, selection)
  const {price, actual: discountedPrice = '0.00'} = priceData
  const totalDiscount = getTotalDiscount(price, discountedPrice)
  const hasDiscount = Number(totalDiscount) > 0
  const liveLabel = formatPurchaseLiveLabel(live, props.kind)
  const resource = buildPurchaseResource(selection)

  return (
    <Card className="flex-none basis-90 p-6 flex flex-col gap-6 relative">
      <h3>订单详情</h3>
      <ul className="flex flex-col gap-3">
        <li className="flex justify-between items-center">
          <span className="text-sm text-gray-500">套餐名称</span>
          <span className="text-sm">{mode === '2' ? '包量套餐' : '包时套餐'}</span>
        </li>
        <li className="flex justify-between items-center">
          <span className="text-sm text-gray-500">IP 时效</span>
          <span className="text-sm">{liveLabel}</span>
        </li>
        {mode === '2' ? (
          <>
            <li className="flex justify-between items-center">
              <span className="text-sm text-gray-500">购买 IP 量</span>
              <span className="text-sm">{quota} 个</span>
            </li>
            <li className="flex justify-between items-center">
              <span className="text-sm text-gray-500">原价</span>
              <span className="text-sm">￥{price}</span>
            </li>
            {hasDiscount && (
              <li className="flex justify-between items-center">
                <span className="text-sm text-gray-500">总折扣</span>
                <span className="text-sm">-￥{totalDiscount}</span>
              </li>
            )}
          </>
        ) : (
          <>
            <li className="flex justify-between items-center">
              <span className="text-sm text-gray-500">套餐时长</span>
              <span className="text-sm">{expire} 天</span>
            </li>
            <li className="flex justify-between items-center">
              <span className="text-sm text-gray-500">每日限额</span>
              <span className="text-sm">{dailyLimit} 个</span>
            </li>
            <li className="flex justify-between items-center">
              <span className="text-sm text-gray-500">原价</span>
              <span className="text-sm">￥{price}</span>
            </li>
            {hasDiscount && (
              <li className="flex justify-between items-center">
                <span className="text-sm text-gray-500">总折扣</span>
                <span className="text-sm">-￥{totalDiscount}</span>
              </li>
            )}
          </>
        )}
      </ul>
      <div className="border-b border-gray-200"></div>
      <p className="flex justify-between items-center">
        <span>实付价格</span>
        <span className="text-xl text-orange-500">￥{discountedPrice}</span>
      </p>
      {profile ? (
        profile.id_type !== 0 ? (
          <>
            <FieldPayment balance={profile.balance}/>
            <Pay
              method={method}
              balance={profile.balance}
              amount={discountedPrice}
              resource={resource}
            />
          </>
        ) : (
          <div className="flex flex-col gap-3">
            <p className="text-sm text-gray-500">
              根据监管要求，您需要完成实名认证后才能支付。
            </p>
            <Link
              href="/admin/identify"
              className={buttonVariants()}
            >
              <IdCard size={16} className="mr-1"/>
              去实名认证
            </Link>
          </div>
        )
      ) : (
        <Link href="/login" className={buttonVariants()}>
          登录后支付
        </Link>
      )}
    </Card>
  )
}

function usePurchasePrice(profile: User | null, selection: PurchaseSelection) {
  const [priceData, setPriceData] = useState<ExtraResp<typeof getPrice>>(emptyPrice)
  const requestIdRef = useRef(0)
  const {kind, mode, live, quota, expire, dailyLimit} = selection

  useEffect(() => {
    const requestId = ++requestIdRef.current

    const loadPrice = async () => {
      try {
        const resource = buildPurchaseResource({
          kind,
          mode,
          live,
          quota,
          expire,
          dailyLimit,
        })
        const response = profile
          ? await getPrice(resource)
          : await getPriceHome(resource)

        if (requestId !== requestIdRef.current) {
          return
        }

        if (!response.success) {
          throw new Error(response.message || '获取价格失败')
        }

        setPriceData({
          price: response.data.price,
          actual: response.data.actual ?? response.data.price ?? '0.00',
          discounted: response.data.discounted ?? '0.00',
        })
      }
      catch (error) {
        if (requestId !== requestIdRef.current) {
          return
        }

        console.error('获取价格失败:', error)
        setPriceData(emptyPrice)
      }
    }

    loadPrice()
  }, [dailyLimit, expire, kind, live, mode, profile, quota])

  return priceData
}

function getTotalDiscount(price: string, discountedPrice: string) {
  const originalPrice = Number.parseFloat(price)
  const actualPrice = Number.parseFloat(discountedPrice)

  if (Number.isNaN(originalPrice) || Number.isNaN(actualPrice)) {
    return '0.00'
  }

  return (originalPrice - actualPrice).toFixed(2)
}
