import type { CSSProperties } from 'react'
import { Alert, Card, Collapse, Descriptions, Space, Table, Tabs, Tag, Typography } from 'antd'
import EndpointDoc, { CommonResponseDoc } from '../openapi/EndpointDoc'
import {
  commonResponseFields,
  endpoints,
  errorCodes,
  orderStatusTable,
  paymentStatusTable,
} from '../openapi/endpoints'

const { Title, Paragraph, Text } = Typography

const baseUrl =
  typeof window !== 'undefined'
    ? window.location.origin.replace(':5173', ':8080')
    : 'http://localhost:8080'

const preStyle: CSSProperties = {
  margin: 0,
  padding: 12,
  background: '#f6f8fa',
  borderRadius: 6,
  fontSize: 12.5,
  lineHeight: 1.6,
  overflow: 'auto',
  whiteSpace: 'pre-wrap',
  wordBreak: 'break-all',
}

export default function OpenApiDocs() {
  return (
    <div>
      <Title level={4} style={{ marginTop: 0 }}>
        开放接口
      </Title>
      <Paragraph type="secondary">
        面向商户系统、履约器和外部平台调用的通用开放 API。凭证在「商户中心 / API 客户端」创建，
        采用 <Text code>X-App-Key</Text> + HMAC-SHA256 签名鉴权。
        原 <Text code>/api/open/v1</Text> 保留给上游发货对接，不在本页展示。
      </Paragraph>

      <Tabs
        items={[
          {
            key: 'overview',
            label: '概览',
            children: <OverviewTab />,
          },
          {
            key: 'auth',
            label: '鉴权与签名',
            children: <AuthTab />,
          },
          {
            key: 'endpoints',
            label: '接口列表',
            children: <EndpointsTab />,
          },
          {
            key: 'status',
            label: '状态说明',
            children: <StatusTab />,
          },
        ]}
      />
    </div>
  )
}

function OverviewTab() {
  return (
    <Space direction="vertical" size="middle" style={{ width: '100%' }}>
      <Alert
        type="info"
        showIcon
        message="一句话上手"
        description={
          <ol style={{ margin: 0, paddingLeft: 20 }}>
            <li>在「商户中心 / API 客户端」创建凭证，获得 <Text code>AppKey</Text> 与 <Text code>AppSecret</Text>。</li>
            <li>每次请求携带 <Text code>X-App-Key / X-Timestamp / X-Nonce / X-Sign</Text> 四个鉴权头。</li>
            <li>调用「商品列表」拿到可售 <Text code>sku</Text>，调用「下单」创建订单并扣款。</li>
            <li>履约器通过「发货回传」回写 processing/success/failed，状态可由「查询订单」轮询。</li>
          </ol>
        }
      />
      <Card size="small" title="环境信息">
        <Descriptions size="small" column={1} bordered>
          <Descriptions.Item label="Base URL">
            <Text code>{baseUrl}</Text>
          </Descriptions.Item>
          <Descriptions.Item label="鉴权头">
            <Text code>X-App-Key</Text>、<Text code>X-Timestamp</Text>、<Text code>X-Nonce</Text>、<Text code>X-Sign</Text>
          </Descriptions.Item>
          <Descriptions.Item label="时间偏差">允许 ±300 秒</Descriptions.Item>
          <Descriptions.Item label="请求体">POST 请求使用 <Text code>application/json</Text></Descriptions.Item>
        </Descriptions>
      </Card>
      <CommonResponseDoc fields={commonResponseFields} errors={errorCodes} />
    </Space>
  )
}

function AuthTab() {
  return (
    <Space direction="vertical" size="middle" style={{ width: '100%' }}>
      <Card size="small" title="鉴权头（每次请求必带）">
        <Table
          size="small"
          pagination={false}
          rowKey="header"
          dataSource={[
            { header: 'X-App-Key', required: true, desc: '商户分配的 AppKey' },
            { header: 'X-Timestamp', required: true, desc: '当前 Unix 秒时间戳' },
            { header: 'X-Nonce', required: true, desc: '随机串，8~96 字符，同一客户端有效期内不可重复' },
            { header: 'X-Sign', required: true, desc: 'HMAC-SHA256 签名，见下方算法' },
          ]}
          columns={[
            { title: 'Header', dataIndex: 'header', width: 160, render: (v) => <Text code>{v}</Text> },
            { title: '必填', dataIndex: 'required', width: 80, render: (v) => v ? <Tag color="red">是</Tag> : <Tag>否</Tag> },
            { title: '说明', dataIndex: 'desc' },
          ]}
        />
      </Card>

      <Card size="small" title="签名算法">
        <Descriptions size="small" column={1} bordered>
          <Descriptions.Item label="签名内容">
            <Text code>{'timestamp\nnonce\nMETHOD\npath\nsha256(body)'}</Text>
          </Descriptions.Item>
          <Descriptions.Item label="拼接方式">按固定顺序，用换行符 <Text code>\n</Text> 拼接</Descriptions.Item>
          <Descriptions.Item label="METHOD">大写，如 GET / POST</Descriptions.Item>
          <Descriptions.Item label="path">仅 URL.Path，不含域名和 query</Descriptions.Item>
          <Descriptions.Item label="body">GET 为空字节；POST 必须与实际发送 body 完全一致</Descriptions.Item>
          <Descriptions.Item label="X-Sign">
            <Text code>hex( HMAC-SHA256( app_secret, 签名内容 ) )</Text>，小写十六进制
          </Descriptions.Item>
        </Descriptions>
      </Card>

      <Card size="small" title="签名示例（GET，body 为空）">
        <pre style={preStyle}>{`timestamp
nonce
GET
/api/client/v1/products
sha256("") = e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855`}</pre>
      </Card>

      <Card size="small" title="签名示例（POST，body 非空）">
        <pre style={preStyle}>{`timestamp
nonce
POST
/api/client/v1/orders
sha256(body) = <实际请求 body 字节的 SHA256 十六进制>`}</pre>
      </Card>

      <Alert
        type="warning"
        showIcon
        message="签名注意事项"
        description={
          <ul style={{ margin: 0, paddingLeft: 20 }}>
            <li>POST 签名用的 <Text code>body</Text> 必须与实际发送的 body <b>字节级一致</b>，不要签名后再改空格或字段顺序。</li>
            <li>签名失败常见原因：secret 错、path 多了 query、body 不一致、时间戳过期、nonce 重复。</li>
            <li>下单接口还需携带 <Text code>Idempotency-Key</Text>，且必须与 <Text code>client_order_no</Text> 一致。</li>
          </ul>
        }
      />
    </Space>
  )
}

function EndpointsTab() {
  return (
    <Collapse
      accordion
      items={endpoints.map((spec) => ({
        key: spec.key,
        label: (
          <Space size="small">
            <Tag color={spec.method === 'GET' ? 'blue' : 'green'} style={{ margin: 0, fontWeight: 700 }}>
              {spec.method}
            </Tag>
            <Text code style={{ fontSize: 13 }}>{spec.path}</Text>
            <Text type="secondary" style={{ fontSize: 12 }}>{spec.summary}</Text>
          </Space>
        ),
        children: <EndpointDoc spec={spec} />,
      }))}
    />
  )
}

function StatusTab() {
  return (
    <Space direction="vertical" size="middle" style={{ width: '100%' }}>
      <Card size="small" title="履约状态 fulfillment_status 与 can_fulfill">
        <Table
          size="small"
          pagination={false}
          rowKey="name"
          dataSource={orderStatusTable}
          columns={[
            { title: '状态', dataIndex: 'name', width: 140, render: (v) => <Text code>{v}</Text> },
            {
              title: 'can_fulfill',
              dataIndex: 'example',
              width: 160,
              render: (v: string) =>
                v === 'can_fulfill=true' ? <Tag color="green">true</Tag> : <Tag>false</Tag>,
            },
            { title: '说明', dataIndex: 'desc' },
          ]}
        />
      </Card>
      <Card size="small" title="支付状态 payment_status">
        <Table
          size="small"
          pagination={false}
          rowKey="name"
          dataSource={paymentStatusTable}
          columns={[
            { title: '状态', dataIndex: 'name', width: 140, render: (v) => <Text code>{v}</Text> },
            { title: '说明', dataIndex: 'desc' },
          ]}
        />
      </Card>
      <Alert
        type="info"
        showIcon
        message="推荐调用流程"
        description={
          <pre style={{ ...preStyle, background: 'transparent', padding: 0 }}>{`拿到 sku（商品列表）
    ↓
POST /orders 下单（幂等，Idempotency-Key = client_order_no）
    ↓
（履约器）POST /orders/{order_no}/ship-notify ship_status=processing
    ↓
按 product.sku 发货
    ↓
POST /orders/{order_no}/ship-notify ship_status=success 或 failed
    ↓
（可选）GET /orders/{order_no} 轮询确认 fulfillment_status=succeeded`}</pre>
        }
      />
    </Space>
  )
}
