import { useEffect, useMemo, useState } from 'react'
import { useNavigate, useLocation } from 'react-router-dom'
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 OpenStatRow = {
  key: number
  label: string
  newCount: number
  mnpCount: number
  rewardCount: number
  changeCount: number
  agingCount: number
  tempCount: number
  prepaidCount: number
  totalCount: number
  settleAmount: number
  afterCount: number
  afterAmount: number
  withdrawCount: number
  margin: number
  _summary?: boolean
}

type OpenStatData = {
  mode: 'daily' | 'monthly'
  year: number
  month?: number
  title: string
  rows: OpenStatRow[]
  totals: OpenStatRow
  today?: number | null
  currentMonth?: number | null
}

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 ReportOpenPage() {
  const navigate = useNavigate()
  const location = useLocation()
  const mode: 'daily' | 'monthly' = location.pathname.includes('open-monthly') ? 'monthly' : 'daily'
  const now = useMemo(() => dayjs(), [])
  const [form] = Form.useForm()
  const [filters, setFilters] = useState<Record<string, unknown>>({
    mode,
    year: now.year(),
    month: now.month() + 1 })

  useEffect(() => {
    setFilters((prev) => ({
      ...prev,
      mode,
      month: mode === 'daily' ? (prev.month ?? now.month() + 1) : undefined }))
  }, [mode, now])

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

  const query = useQuery({
    queryKey: ['open-stats', filters],
    queryFn: async () => {
      const { data } = await client.get<ApiResponse<OpenStatData>>(`${apiPrefix()}/reports/open-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 outOptions = useMemo(
    () => (companies.data?.items ?? [])
      .filter((c) => ['SHOP', 'OUT'].includes(String(c.type)))
      .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 shiftYear = (delta: number) => {
    const year = Number(form.getFieldValue('year') ?? now.year())
    form.setFieldsValue({ year: year + delta })
  }

  const onSearch = (values: Record<string, unknown>) => {
    setFilters({
      mode,
      year: values.year,
      month: mode === 'daily' ? values.month : undefined,
      telecom: values.telecom,
      incompanyId: values.incompanyId,
      outcompanyId: values.outcompanyId,
      outCategory: values.outCategory })
  }

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

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

  const switchMode = (next: 'daily' | 'monthly') => {
    navigate(next === 'daily' ? '/care/report/open' : '/care/report/open-monthly')
    const values = form.getFieldsValue()
    setFilters({
      mode: next,
      year: values.year ?? now.year(),
      month: next === 'daily' ? (values.month ?? now.month() + 1) : undefined,
      telecom: values.telecom,
      incompanyId: values.incompanyId,
      outcompanyId: values.outcompanyId,
      outCategory: values.outCategory })
  }

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

  const dateTitle = mode === 'daily'
    ? `${filters.year}년 ${filters.month}월`
    : `${filters.year}년`

  const columns = [
    {
      title: dateTitle,
      dataIndex: 'label',
      width: 100,
      align: 'center' as const,
      fixed: 'left' as const,
      render: (v: string) => {
        if (v === '합계') return <b>{v}</b>
        if (mode === 'daily') {
          if (v.includes('(토)')) return <span className="open-stat-sat">{v}</span>
          if (v.includes('(일)')) return <span className="open-stat-sun">{v}</span>
        }
        return v
      } },
    { title: '신규', dataIndex: 'newCount', width: 70, align: 'center' as const, render: cell },
    { title: 'MNP', dataIndex: 'mnpCount', width: 70, align: 'center' as const, render: cell },
    { title: '보상', dataIndex: 'rewardCount', width: 70, align: 'center' as const, render: cell },
    { title: '기변', dataIndex: 'changeCount', width: 70, align: 'center' as const, render: cell },
    { title: '에이징', dataIndex: 'agingCount', width: 70, align: 'center' as const, render: cell },
    { title: '가개통', dataIndex: 'tempCount', width: 70, align: 'center' as const, render: cell },
    { title: '선불개통', dataIndex: 'prepaidCount', width: 80, align: 'center' as const, render: cell },
    { title: '합계', dataIndex: 'totalCount', width: 70, align: 'center' as const, render: (v: number) => (num(v) ? <b>{num(v).toLocaleString()}</b> : '') },
    { title: '정산금액', dataIndex: 'settleAmount', width: 100, align: 'center' as const, render: money },
    { title: '후정산', dataIndex: 'afterCount', width: 70, align: 'center' as const, render: cell },
    { title: '후정산금액', dataIndex: 'afterAmount', width: 100, align: 'center' as const, render: money },
    { title: '철회', dataIndex: 'withdrawCount', width: 70, align: 'center' as const, render: cell },
    { title: '마진', dataIndex: 'margin', width: 100, align: 'center' as const, render: money },
  ]

  return (
    <div className="stock-page open-stat-page">
      <div className="stock-title">
        <div>
          <h2><BarChartOutlined style={{ marginRight: 8 }} />개통통계</h2>
          <p>모바일개통에 대한 통계를 일별, 월별로 확인하실 수 있습니다.</p>
        </div>
        <div className="open-stat-toggle">
          <Button
            className={mode === 'daily' ? 'open-stat-toggle-on' : ''}
            onClick={() => switchMode('daily')}
          >
            일별통계
          </Button>
          <Button
            className={mode === 'monthly' ? 'open-stat-toggle-on' : ''}
            onClick={() => switchMode('monthly')}
          >
            월별통계
          </Button>
        </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}
          >
            {mode === 'daily' ? (
              <>
                <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>
              </>
            ) : (
              <>
                <Button onClick={() => shiftYear(-1)}>이전년도</Button>
                <Form.Item name="year"><Select className="w-110" options={yearOptions} /></Form.Item>
                <Button onClick={() => shiftYear(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="outcompanyId">
              <Select allowClear showSearch optionFilterProp="label" placeholder="-출고처-" className="w-130" options={outOptions} />
            </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="key"
          dataSource={dataSource}
          columns={columns}
          pagination={false}
          scroll={{ x: 1200 }}
          rowClassName={(row) => {
            if (row._summary) return 'open-stat-summary'
            if (mode === 'daily' && query.data?.today != null && row.key === query.data.today) return 'open-stat-today'
            if (mode === 'monthly' && query.data?.currentMonth != null && row.key === query.data.currentMonth) return 'open-stat-today'
            return ''
          }}
          locale={{ emptyText: '등록되어 있는 자료가 없습니다.' }}
        />
      </Card>
    </div>
  )
}
