import { useMemo, useState } from 'react'
import { useQuery } from '@tanstack/react-query'
import dayjs from 'dayjs'
import { Button, Card, Form, Select, Space, message } from 'antd'
import CareTable from '../../components/CareTable'
import { BarChartOutlined, FileTextOutlined, SearchOutlined } from '@ant-design/icons'
import client, { apiPrefix, unwrap, type ApiResponse } from '../../api/client'
import { resourceApi } from '../../api/resources'

type OutStatRow = {
  id: number
  region: string
  name: string
  openCount: number
  openAmount: number
  afterCount: number
  afterAmount: number
  homeCount: number
  homeAmount: number
  realSettleAmount: number
  margin: number
  _summary?: boolean
}

type OutStatData = {
  year: number
  month: number
  title: string
  total: number
  rows: OutStatRow[]
  totals: OutStatRow
}

const num = (v: unknown) => {
  const n = Number(v ?? 0)
  return Number.isFinite(n) ? n : 0
}
const cell = (v: unknown) => (num(v) === 0 ? '' : num(v).toLocaleString())
const money = (v: unknown) => (num(v) === 0 ? '' : num(v).toLocaleString())

export default function ReportOutPage() {
  const now = useMemo(() => dayjs(), [])
  const [form] = Form.useForm()
  const [filters, setFilters] = useState<Record<string, unknown>>({
    year: now.year(),
    month: now.month() + 1 })

  const companies = useQuery({
    queryKey: ['out-stats-companies'],
    queryFn: () => resourceApi.list('companies', { size: 200 }) })

  const query = useQuery({
    queryKey: ['outcompany-stats', filters],
    queryFn: async () => {
      const { data } = await client.get<ApiResponse<OutStatData>>(`${apiPrefix()}/reports/outcompany-stats`, {
        params: filters })
      return unwrap(data)
    } })

  const inOptions = useMemo(
    () => (companies.data?.items ?? [])
      .filter((c) => String(c.type) === 'IN')
      .map((c) => ({ value: Number(c.id), label: String(c.name) })),
    [companies.data],
  )

  const yearOptions = useMemo(() => {
    const years: number[] = []
    for (let y = now.year(); y >= now.year() - 5; y--) years.push(y)
    return years.map((y) => ({ value: y, label: `${y}년` }))
  }, [now])

  const monthOptions = useMemo(
    () => Array.from({ length: 12 }, (_, i) => ({ value: i + 1, label: `${i + 1}월` })),
    [],
  )

  const shiftMonth = (delta: number) => {
    const year = Number(form.getFieldValue('year') ?? now.year())
    const month = Number(form.getFieldValue('month') ?? now.month() + 1)
    const next = dayjs(`${year}-${String(month).padStart(2, '0')}-01`).add(delta, 'month')
    form.setFieldsValue({ year: next.year(), month: next.month() + 1 })
  }

  const onSearch = (values: Record<string, unknown>) => {
    setFilters({
      year: values.year,
      month: values.month,
      telecom: values.telecom,
      incompanyId: values.incompanyId,
      outCategory: values.outCategory })
  }

  const onReset = () => {
    const init = { year: now.year(), month: now.month() + 1, telecom: undefined, incompanyId: undefined, outCategory: undefined }
    form.setFieldsValue(init)
    setFilters({ year: init.year, month: init.month })
  }

  const download = async () => {
    try {
      const { data } = await client.get(`${apiPrefix()}/reports/outcompany-stats/export`, {
        params: filters,
        responseType: 'blob' })
      const url = URL.createObjectURL(data)
      const a = document.createElement('a')
      a.href = url
      a.download = `출고처통계_${filters.year}-${filters.month}.csv`
      a.click()
      URL.revokeObjectURL(url)
    } catch {
      message.error('엑셀 다운로드에 실패했습니다.')
    }
  }

  const dataSource = useMemo(() => {
    const list = query.data?.rows ?? []
    if (!list.length || !query.data?.totals) return list
    return [
      ...list,
      {
        ...query.data.totals,
        id: -1,
        region: '합계',
        name: '',
        _summary: true },
    ]
  }, [query.data])

  const dateTitle = `${filters.year}년 ${filters.month}월`

  const columns = [
    {
      title: dateTitle,
      dataIndex: 'region',
      width: 90,
      align: 'center' as const,
          render: (v: string, row: OutStatRow) => (row._summary ? <b>{v}</b> : v),
      onCell: (row: OutStatRow) => (row._summary ? { colSpan: 2 } : {}) },
    {
      title: '',
      dataIndex: 'name',
      width: 140,
      align: 'center' as const,
      onCell: (row: OutStatRow) => (row._summary ? { colSpan: 0 } : {}),
      render: (v: string) => v },
    { title: '개통', dataIndex: 'openCount', width: 80, align: 'center' as const, render: cell },
    { title: '개통금액', dataIndex: 'openAmount', width: 110, align: 'center' as const, render: money },
    { title: '후정산', dataIndex: 'afterCount', width: 80, align: 'center' as const, render: cell },
    { title: '후정산금액', dataIndex: 'afterAmount', width: 110, align: 'center' as const, render: money },
    { title: '홈상품', dataIndex: 'homeCount', width: 80, align: 'center' as const, render: cell },
    { title: '홈상품금액', dataIndex: 'homeAmount', width: 110, align: 'center' as const, render: money },
    { title: '실정산금액', dataIndex: 'realSettleAmount', width: 110, align: 'center' as const, render: money },
    { title: '마진', dataIndex: 'margin', width: 110, align: 'center' as const, render: money },
  ]

  return (
    <div className="stock-page open-stat-page out-stat-page">
      <div className="stock-title">
        <div>
          <h2><BarChartOutlined style={{ marginRight: 8 }} />출고처통계</h2>
          <p>출고처별로 정산에 대한 통계를 확인하실 수 있습니다.</p>
        </div>
      </div>

      <Card className="stock-filter-card" size="small">
        <div className="open-stat-filter-row">
          <Form
            form={form}
            layout="inline"
            className="open-stat-filter"
            initialValues={{ year: now.year(), month: now.month() + 1 }}
            onFinish={onSearch}
          >
            <Button onClick={() => shiftMonth(-1)}>전월</Button>
            <Form.Item name="year"><Select className="w-110" options={yearOptions} /></Form.Item>
            <Form.Item name="month"><Select className="w-100" options={monthOptions} /></Form.Item>
            <Button onClick={() => shiftMonth(1)}>익월</Button>
            <Form.Item name="telecom">
              <Select allowClear placeholder="-통신사-" className="w-110" options={['SKT', 'KT', 'LGU+'].map((v) => ({ value: v, label: v }))} />
            </Form.Item>
            <Form.Item name="incompanyId">
              <Select allowClear showSearch optionFilterProp="label" placeholder="-입고처-" className="w-130" options={inOptions} />
            </Form.Item>
            <Form.Item name="outCategory">
              <Select allowClear placeholder="-출고분류-" className="w-110" options={['판매점', '도매'].map((v) => ({ value: v, label: v }))} />
            </Form.Item>
            <Form.Item>
              <Space>
                <Button type="primary" htmlType="submit" icon={<SearchOutlined />}>검색</Button>
                <Button onClick={onReset}>초기화</Button>
              </Space>
            </Form.Item>
          </Form>
          <Button type="link" icon={<FileTextOutlined />} onClick={download}>엑셀다운로드</Button>
        </div>
      </Card>

      <Card className="stock-table-card" size="small">
        <CareTable
          size="small"
          bordered
          loading={query.isLoading}
          rowKey="id"
          dataSource={dataSource}
          columns={columns}
          pagination={false}
          scroll={{ x: 1100 }}
          rowClassName={(row) => (row._summary ? 'open-stat-summary' : '')}
          locale={{ emptyText: '등록되어 있는 자료가 없습니다.' }}
        />
      </Card>
    </div>
  )
}
