import { useMemo, useState } from 'react'
import { useQuery } 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 { CloseOutlined, DownloadOutlined, FileProtectOutlined, SearchOutlined } from '@ant-design/icons'
import client, { apiPrefix, unwrap, type ApiResponse } from '../../api/client'
import { resourceApi } from '../../api/resources'

const { RangePicker } = DatePicker
const searchTypes = ['고객명', '미비서류', '휴대폰(뒷4자리)']
const options = (values: string[]) => values.map((value) => ({ value, label: value }))
const money = (v: unknown) => (v == null || v === '' ? '-' : Number(v).toLocaleString())

type HomeIndocRow = Record<string, unknown> & { id: number }
type HomeIndocFilters = {
  dateFrom?: string
  dateTo?: string
  telecom?: string
  incompanyId?: number | string
  outcompanyName?: string
  searchType?: string
  keyword?: string
  page: number
  size: number
}

export default function OpenHomeIndocPage() {
  const [form] = Form.useForm()
  const [searched, setSearched] = useState(false)
  const [filters, setFilters] = useState<HomeIndocFilters>({ page: 0, size: 15, searchType: '고객명' })

  const companies = useQuery({ queryKey: ['homeindoc-companies'], queryFn: () => resourceApi.list('companies', { size: 200 }) })
  const inOptions = useMemo(
    () => (companies.data?.items ?? []).filter((c) => String(c.type) === 'IN').map((c) => ({ value: c.id, label: String(c.name) })),
    [companies.data],
  )

  const enabled = searched && !!filters.dateFrom && !!filters.dateTo
  const query = useQuery({
    queryKey: ['homeindoc-search', filters],
    queryFn: async () => {
      const { data } = await client.get<ApiResponse<{ total: number; list: HomeIndocRow[] }>>(`${apiPrefix()}/homeindocs/search`, { params: filters })
      return unwrap(data)
    },
    enabled })

  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
    if (!dates?.[0] || !dates?.[1]) {
      message.warning('날짜를 선택하세요.')
      return
    }
    setSearched(true)
    setFilters({
      dateFrom: dates[0].format('YYYY-MM-DD'),
      dateTo: dates[1].format('YYYY-MM-DD'),
      telecom: values.telecom ? String(values.telecom) : undefined,
      incompanyId: values.incompanyId as number | string | undefined,
      outcompanyName: values.outcompanyName ? String(values.outcompanyName) : undefined,
      searchType: String(values.searchType || '고객명'),
      keyword: values.keyword ? String(values.keyword) : undefined,
      page: 0,
      size: Number(values.size ?? 15) })
  }

  const clearDates = () => {
    form.setFieldValue('dates', undefined)
    setSearched(false)
    setFilters((prev) => ({ page: 0, size: prev.size, searchType: prev.searchType || '고객명' }))
  }

  const download = async () => {
    if (!filters.dateFrom || !filters.dateTo) {
      message.warning('날짜를 선택하세요.')
      return
    }
    const { data } = await client.get(`${apiPrefix()}/homeindocs/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)
  }

  const columns = [
    { title: '설치일', dataIndex: 'installDate', width: 100 },
    { title: '통신사', dataIndex: 'telecom', width: 72 },
    { title: '입고처', dataIndex: 'incompanyName', width: 110, ellipsis: true },
    { title: '출고처', dataIndex: 'outcompanyName', width: 110, ellipsis: true },
    { title: '고객명', dataIndex: 'customerName', width: 90 },
    { title: '휴대폰', dataIndex: 'phone', width: 120 },
    { title: '가입상품', dataIndex: 'products', width: 140, ellipsis: true },
    { title: '미비서류', dataIndex: 'missingDocs', width: 160, ellipsis: true },
    { title: '차감금', dataIndex: 'deductAmount', width: 90, align: 'right' as const, render: money },
    { title: '차감사유', dataIndex: 'deductReason', width: 120, ellipsis: true },
    { title: '마감일', dataIndex: 'deadline', width: 100 },
    { title: '상태', dataIndex: 'status', width: 70 },
  ]

  return (
    <div className="stock-page home-indoc-page">
      <div className="stock-title">
        <div>
          <h2><FileProtectOutlined style={{ marginRight: 8 }} />홈상품미비서류</h2>
          <p>홈상품 미비서류에 등록된 내역을 모두 확인하실 수 있습니다.</p>
        </div>
      </div>

      <Card className="stock-filter-card" size="small">
        <Form
          form={form}
          layout="inline"
          className="home-indoc-filter"
          initialValues={{ searchType: '고객명', 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="telecom">
              <Select allowClear placeholder="-통신사-" className="w-110" options={options(['SKT', 'KT', 'LGU+'])} />
            </Form.Item>
            <Form.Item name="incompanyId">
              <Select allowClear placeholder="-입고처-" className="w-150" options={inOptions} />
            </Form.Item>
            <Form.Item name="outcompanyName">
              <Input placeholder="출고처" className="w-130" allowClear />
            </Form.Item>
            <Form.Item name="searchType">
              <Select className="w-130" 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>
            <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)
                  if (searched) setFilters((prev) => ({ ...prev, size, page: 0 }))
                }}
              />
            </Form.Item>
          </div>
        </Form>
      </Card>

      <Card className="stock-table-card sheet-result-card" size="small">
        {!enabled ? (
          <div className="sheet-empty">미비서류내역은 검색 후 확인하실 수 있습니다.</div>
        ) : (
          <>
            <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}
              scroll={{ x: 1400 }}
              pagination={{
                current: filters.page + 1,
                pageSize: filters.size,
                total: query.data?.total,
                showSizeChanger: false,
                showTotal: (total) => `총 ${total}건`,
                onChange: (page) => setFilters((prev) => ({ ...prev, page: page - 1 })) }}
            />
          </>
        )}
      </Card>
    </div>
  )
}
