import { useMemo, useState } from 'react'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import dayjs, { type Dayjs } from 'dayjs'
import { Button, Card, DatePicker, Form, Input, Select, Space, Typography, message } from 'antd'
import CareTable from '../../components/CareTable'
import Modal from '../../components/DraggableModal'
import {
  CloseOutlined, DownloadOutlined, ReloadOutlined, RollbackOutlined, SearchOutlined } from '@ant-design/icons'
import client, { apiPrefix, unwrap, type ApiResponse } from '../../api/client'

const { RangePicker } = DatePicker
const searchTypes = ['개통번호(뒷4자리)', '고객명', '사유 및 비고']

type WithdrawalRow = Record<string, unknown> & { id: number; no?: number }
type WithdrawalData = { total: number; list: WithdrawalRow[] }

const initial = { page: 0, size: 15, searchType: '개통번호(뒷4자리)' } as Record<string, unknown>

const withdrawalApi = {
  async search(params: Record<string, unknown>) {
    const { data } = await client.get<ApiResponse<WithdrawalData>>(`${apiPrefix()}/withdrawals/search`, { params })
    return unwrap(data)
  },
  async remove(ids: number[]) {
    const { data } = await client.post<ApiResponse>(`${apiPrefix()}/withdrawals/delete`, { ids })
    return unwrap(data)
  } }

export default function OpenWithdrawPage() {
  const [form] = Form.useForm()
  const qc = useQueryClient()
  const [selected, setSelected] = useState<number[]>([])
  const [filters, setFilters] = useState<Record<string, unknown>>(initial)

  const query = useQuery({
    queryKey: ['open-withdraw', filters],
    queryFn: () => withdrawalApi.search(filters) })

  const remove = useMutation({
    mutationFn: () => withdrawalApi.remove(selected),
    onSuccess: () => {
      message.success('삭제했습니다.')
      setSelected([])
      qc.invalidateQueries({ queryKey: ['open-withdraw'] })
    },
    onError: (e: Error) => message.error(e.message) })

  const setPreset = (from: Dayjs, to: Dayjs) => form.setFieldsValue({ dates: [from, to] })

  const onSearch = (values: Record<string, unknown>) => {
    const dates = values.dates as [Dayjs, Dayjs] | undefined
    setSelected([])
    setFilters({
      ...initial,
      outcompanyName: values.outcompanyName ? String(values.outcompanyName) : undefined,
      searchType: values.searchType || '개통번호(뒷4자리)',
      keyword: values.keyword ? String(values.keyword) : undefined,
      dateFrom: dates?.[0]?.format('YYYY-MM-DD'),
      dateTo: dates?.[1]?.format('YYYY-MM-DD'),
      page: 0,
      size: values.size ?? filters.size ?? 15 })
  }

  const reset = () => {
    form.resetFields()
    form.setFieldsValue({ searchType: '개통번호(뒷4자리)', size: 15 })
    setSelected([])
    setFilters(initial)
  }

  const clearDates = () => form.setFieldValue('dates', undefined)

  const download = async () => {
    try {
      const { data } = await client.get(`${apiPrefix()}/withdrawals/export`, { params: filters, responseType: 'blob' })
      const url = URL.createObjectURL(data)
      const a = document.createElement('a')
      a.href = url
      a.download = '개통철회이력.csv'
      a.click()
      URL.revokeObjectURL(url)
    } catch {
      message.error('엑셀 다운로드에 실패했습니다.')
    }
  }

  const columns = useMemo(() => [
    { title: '번호', dataIndex: 'no', width: 64, align: 'center' as const },
    { title: '철회일', dataIndex: 'withdrawDate', width: 110 },
    { title: '출고처', dataIndex: 'outcompanyName', width: 130, ellipsis: true },
    { title: '고객명', dataIndex: 'customerName', width: 90 },
    { title: '개통일', dataIndex: 'openDate', width: 110 },
    { title: '개통번호', dataIndex: 'openphone', width: 130 },
    { title: '처리직원', dataIndex: 'processor', width: 90 },
    { title: '처리일', dataIndex: 'processedAt', width: 140 },
    { title: '사유 및 비고', dataIndex: 'reason', width: 160, ellipsis: true, render: (v: string) => v || '-' },
  ], [])

  return (
    <div className="stock-page withdraw-page">
      <div className="stock-title">
        <div>
          <h2><RollbackOutlined style={{ marginRight: 8 }} />개통 철회이력</h2>
          <p>모바일 개통과 관련된 이력을 확인하실 수 있습니다.</p>
        </div>
        <Space className="stock-title-actions" wrap align="start">
          <Typography.Text type="secondary" className="sheet-notice">* 대표권한은 이력을 삭제하실 수 있습니다.</Typography.Text>
          <Button
            disabled={!selected.length}
            loading={remove.isPending}
            onClick={() => {
              if (!selected.length) {
                message.warning('삭제할 이력을 선택하세요.')
                return
              }
              Modal.confirm({
                title: '이력 삭제',
                content: `선택한 ${selected.length}건의 이력을 삭제하시겠습니까?`,
                onOk: () => remove.mutateAsync() })
            }}
          >
            삭제
          </Button>
        </Space>
      </div>

      <Card className="stock-filter-card" size="small">
        <Form
          form={form}
          layout="inline"
          className="withdraw-filter"
          initialValues={{ searchType: '개통번호(뒷4자리)', size: 15 }}
          onFinish={onSearch}
        >
          <div className="stock-filter-row">
            <Form.Item name="dates">
              <RangePicker className="w-230" placeholder={['YYYY-MM-DD', 'YYYY-MM-DD']} />
            </Form.Item>
            <Space.Compact className="sheet-presets">
              <Button onClick={() => setPreset(dayjs(), dayjs())}>오늘</Button>
              <Button onClick={() => setPreset(dayjs().subtract(6, 'day'), dayjs())}>1주일</Button>
              <Button onClick={() => setPreset(dayjs().startOf('month'), dayjs().endOf('month'))}>당월</Button>
              <Button onClick={() => setPreset(dayjs().subtract(1, 'month').startOf('month'), dayjs().subtract(1, 'month').endOf('month'))}>전월</Button>
              <Button onClick={() => setPreset(dayjs().subtract(2, 'month').startOf('month'), dayjs().subtract(2, 'month').endOf('month'))}>전전월</Button>
            </Space.Compact>
            <Button className="sheet-clear" icon={<CloseOutlined />} onClick={clearDates} />
            <Form.Item name="outcompanyName">
              <Input placeholder="출고처" className="w-130" allowClear />
            </Form.Item>
            <Form.Item name="searchType">
              <Select className="w-150" options={searchTypes.map((v) => ({ value: v, label: v }))} />
            </Form.Item>
            <Form.Item name="keyword">
              <Input className="w-130" allowClear />
            </Form.Item>
            <Button type="primary" htmlType="submit" icon={<SearchOutlined />}>검색</Button>
            <Button icon={<ReloadOutlined />} onClick={reset}>초기화</Button>
            <Form.Item name="size" className="sheet-size">
              <Select
                className="w-150"
                options={[15, 30, 50, 100].map((n) => ({ value: n, label: `목록 ${n}개씩 보기` }))}
                onChange={(size) => {
                  form.setFieldValue('size', size)
                  setFilters((prev) => ({ ...prev, size, page: 0 }))
                }}
              />
            </Form.Item>
          </div>
        </Form>
      </Card>

      <Card className="stock-table-card" size="small">
        <div className="recovery-table-head">
          <Typography.Text>목록 <b>{query.data?.total ?? 0}</b></Typography.Text>
          <Button type="link" icon={<DownloadOutlined />} onClick={download}>엑셀다운로드</Button>
        </div>
        <CareTable
          rowKey="id"
          size="small"
          loading={query.isLoading}
          dataSource={query.data?.list}
          columns={columns}
          rowSelection={{
            selectedRowKeys: selected,
            onChange: (keys) => setSelected(keys.map(Number)) }}
          scroll={{ x: 1200 }}
          pagination={{
            current: Number(filters.page) + 1,
            pageSize: Number(filters.size),
            total: query.data?.total,
            showSizeChanger: false,
            showTotal: (total) => `총 ${total}건`,
            onChange: (page) => setFilters((prev) => ({ ...prev, page: page - 1 })) }}
          locale={{ emptyText: '등록되어 있는 자료가 없습니다.' }}
        />
      </Card>
    </div>
  )
}
