import { useMemo, useState } from 'react'
import Modal from '../../components/DraggableModal'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import {
  Button,
  Card,
  Form,
  Input,
  Popover,
  Select,
  Space,
  Typography,
  message } from 'antd'
import CareTable from '../../components/CareTable'
import {
  EditOutlined, FileTextOutlined, InfoCircleOutlined, MailOutlined, PlusOutlined, SearchOutlined, SettingOutlined } from '@ant-design/icons'
import client, { apiPrefix, unwrap, type ApiResponse } from '../../api/client'

type OutCompanyRow = {
  id: number
  status?: string
  active?: boolean
  channel?: string
  category?: string
  name?: string
  pcode?: string
  salesperson?: string
  phone?: string
  managerName?: string
  mobile?: string
  businessName?: string
  businessNumber?: string
  bankAccount?: string
  createdAt?: string
  memo?: string
}

type OutCompanyData = {
  total: number
  list: OutCompanyRow[]
}

const channelOptions = ['도매', '소매', 'C채널', '특판', '기타']
const categoryOptions = ['판매점', '출고처', '도매', '특판', '본사']

export default function OutCompanyPage() {
  const qc = useQueryClient()
  const [form] = Form.useForm()
  const [editForm] = Form.useForm()
  const [memoForm] = Form.useForm()
  const [open, setOpen] = useState(false)
  const [editing, setEditing] = useState<OutCompanyRow | null>(null)
  const [memoOpen, setMemoOpen] = useState(false)
  const [memoTarget, setMemoTarget] = useState<OutCompanyRow | null>(null)
  const [selected, setSelected] = useState<number[]>([])
  const [filters, setFilters] = useState<Record<string, unknown>>({
    searchType: '출고처명',
    page: 0,
    size: 15,
    sort: 'name,asc' })

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

  const refresh = () => {
    setSelected([])
    qc.invalidateQueries({ queryKey: ['outcompanies'] })
  }

  const saveMut = useMutation({
    mutationFn: async (values: Record<string, unknown>) => {
      if (editing?.id) {
        const { data } = await client.put(`${apiPrefix()}/outcompanies/${editing.id}`, values)
        return unwrap(data)
      }
      const { data } = await client.post(`${apiPrefix()}/outcompanies`, values)
      return unwrap(data)
    },
    onSuccess: () => {
      message.success(editing ? '출고처를 수정했습니다.' : '출고처를 등록했습니다.')
      setOpen(false)
      setEditing(null)
      editForm.resetFields()
      refresh()
    },
    onError: (e: Error) => message.error(e.message) })

  const statusMut = useMutation({
    mutationFn: async (status: '사용' | '미사용') => {
      const { data } = await client.post(`${apiPrefix()}/outcompanies/status`, { ids: selected, status })
      return unwrap(data)
    },
    onSuccess: (_d, status) => {
      message.success(`${status} 처리했습니다.`)
      refresh()
    },
    onError: (e: Error) => message.error(e.message) })

  const memoMut = useMutation({
    mutationFn: async (memo: string) => {
      const { data } = await client.put(`${apiPrefix()}/outcompanies/${memoTarget!.id}`, { memo })
      return unwrap(data)
    },
    onSuccess: () => {
      message.success('비고를 저장했습니다.')
      setMemoOpen(false)
      setMemoTarget(null)
      memoForm.resetFields()
      refresh()
    },
    onError: (e: Error) => message.error(e.message) })

  const onSearch = (values: Record<string, unknown>) => {
    setFilters((prev) => ({
      ...prev,
      status: values.status,
      channel: values.channel,
      category: values.category,
      searchType: values.searchType || '출고처명',
      keyword: values.keyword,
      page: 0,
      size: Number(values.size ?? prev.size ?? 15) }))
  }

  const onReset = () => {
    form.setFieldsValue({
      status: undefined,
      channel: undefined,
      category: undefined,
      searchType: '출고처명',
      keyword: undefined,
      size: 15 })
    setFilters({ searchType: '출고처명', page: 0, size: 15, sort: 'name,asc' })
  }

  const openCreate = () => {
    setEditing(null)
    editForm.setFieldsValue({
      name: undefined,
      channel: '도매',
      category: '판매점',
      pcode: undefined,
      salesperson: undefined,
      phone: undefined,
      managerName: undefined,
      mobile: undefined,
      businessName: undefined,
      businessNumber: undefined,
      bankAccount: undefined,
      memo: undefined,
      status: '사용',
      type: 'OUT' })
    setOpen(true)
  }

  const openEdit = (row: OutCompanyRow) => {
    setEditing(row)
    editForm.setFieldsValue({
      name: row.name,
      channel: row.channel,
      category: row.category,
      pcode: row.pcode,
      salesperson: row.salesperson,
      phone: row.phone,
      managerName: row.managerName,
      mobile: row.mobile,
      businessName: row.businessName,
      businessNumber: row.businessNumber,
      bankAccount: row.bankAccount,
      memo: row.memo,
      status: row.status || '사용' })
    setOpen(true)
  }

  const openMemo = (row: OutCompanyRow) => {
    setMemoTarget(row)
    memoForm.setFieldsValue({ memo: row.memo })
    setMemoOpen(true)
  }

  const download = async () => {
    const { data } = await client.get(`${apiPrefix()}/outcompanies/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 = useMemo(() => [
    {
      title: '상태',
      dataIndex: 'status',
      width: 70,
      align: 'center' as const,
      render: (v: string) => <span className={v === '미사용' ? 'farebox-cancelled' : ''}>{v}</span> },
    { title: '채널', dataIndex: 'channel', width: 80, align: 'center' as const, sorter: true },
    { title: '업체명', dataIndex: 'name', width: 140, ellipsis: true, sorter: true },
    { title: 'P코드', dataIndex: 'pcode', width: 90, align: 'center' as const, sorter: true },
    { title: '영업담당', dataIndex: 'salesperson', width: 90, align: 'center' as const },
    { title: '전화', dataIndex: 'phone', width: 120, align: 'center' as const },
    { title: '담당자', dataIndex: 'managerName', width: 90, align: 'center' as const },
    { title: '휴대폰', dataIndex: 'mobile', width: 120, align: 'center' as const },
    { title: '상호', dataIndex: 'businessName', width: 110, ellipsis: true },
    { title: '사업자번호', dataIndex: 'businessNumber', width: 120, align: 'center' as const },
    {
      title: '계좌',
      dataIndex: 'bankAccount',
      width: 70,
      align: 'center' as const,
      render: (v?: string) => (
        v
          ? (
            <Popover content={<div style={{ maxWidth: 260 }}>{v}</div>} title="계좌정보">
              <Button type="text" size="small" icon={<InfoCircleOutlined style={{ color: '#1677ff' }} />} />
            </Popover>
          )
          : null
      ) },
    { title: '등록일', dataIndex: 'createdAt', width: 110, align: 'center' as const, sorter: true },
    {
      title: '비고',
      key: 'memo',
      width: 60,
      align: 'center' as const,
      render: (_: unknown, row: OutCompanyRow) => (
        <Button
          type="text"
          size="small"
          icon={<MailOutlined style={{ color: row.memo ? '#1677ff' : '#94a3b8' }} />}
          onClick={() => openMemo(row)}
        />
      ) },
    {
      title: '관리',
      key: 'manage',
      width: 70,
      align: 'center' as const,
      fixed: 'right' as const,
      render: (_: unknown, row: OutCompanyRow) => (
        <Button type="primary" size="small" className="staff-manage-btn" icon={<FileTextOutlined />} onClick={() => openEdit(row)} />
      ) },
  ], [])

  return (
    <div className="stock-page outcompany-page">
      <div className="stock-title">
        <div>
          <h2><SettingOutlined style={{ marginRight: 8 }} />출고처관리</h2>
          <p>거래하고 있는 출고처(판매점)를 등록 혹은 관리하실 수 있습니다.</p>
        </div>
        <Space className="stock-title-actions" wrap>
          <Button
            className="farebox-gray-btn"
            disabled={!selected.length}
            loading={statusMut.isPending}
            onClick={() => {
              if (!selected.length) { message.warning('항목을 선택하세요.'); return }
              statusMut.mutate('사용')
            }}
          >
            사용
          </Button>
          <Button
            className="farebox-gray-btn"
            disabled={!selected.length}
            loading={statusMut.isPending}
            onClick={() => {
              if (!selected.length) { message.warning('항목을 선택하세요.'); return }
              statusMut.mutate('미사용')
            }}
          >
            미사용
          </Button>
          <Button type="primary" icon={<PlusOutlined />} onClick={openCreate}>출고처 등록</Button>
        </Space>
      </div>

      <Card className="stock-filter-card" size="small">
        <Form
          form={form}
          layout="inline"
          className="farebox-filter"
          initialValues={{ searchType: '출고처명', size: 15 }}
          onFinish={onSearch}
        >
          <div className="farebox-filter-row">
            <Form.Item name="status">
              <Select allowClear placeholder="상태" className="w-110" options={['사용', '미사용'].map((v) => ({ value: v, label: v }))} />
            </Form.Item>
            <Form.Item name="channel">
              <Select allowClear placeholder="채널" className="w-110" options={channelOptions.map((v) => ({ value: v, label: v }))} />
            </Form.Item>
            <Form.Item name="category">
              <Select allowClear placeholder="분류" className="w-110" options={categoryOptions.map((v) => ({ value: v, label: v }))} />
            </Form.Item>
            <Form.Item name="searchType">
              <Select
                className="w-120"
                options={['출고처명', 'P코드', '담당자', '영업담당', '상호', '사업자번호'].map((v) => ({ value: v, label: v }))}
              />
            </Form.Item>
            <Form.Item name="keyword">
              <Input className="w-150" allowClear />
            </Form.Item>
            <Form.Item>
              <Space>
                <Button type="primary" htmlType="submit" icon={<SearchOutlined />}>검색</Button>
                <Button onClick={onReset}>초기화</Button>
              </Space>
            </Form.Item>
            <Form.Item name="size" className="farebox-size">
              <Select
                className="w-150"
                options={[15, 30, 50, 100].map((n) => ({ value: n, label: `목록 ${n}개씩 보기` }))}
                onChange={(size) => setFilters((prev) => ({ ...prev, size, page: 0 }))}
              />
            </Form.Item>
          </div>
        </Form>
      </Card>

      <Card className="stock-table-card" size="small">
        <div className="farebox-table-toolbar">
          <Typography.Text>목록 {query.data?.total ?? 0}</Typography.Text>
          <Button type="link" icon={<FileTextOutlined />} onClick={download}>엑셀다운로드</Button>
        </div>
        <CareTable
          size="small"
          loading={query.isLoading}
          rowKey="id"
          dataSource={query.data?.list}
          columns={columns}
          bordered
          rowSelection={{
            selectedRowKeys: selected,
            onChange: (keys) => setSelected(keys.map(Number)) }}
          pagination={{
            current: Number(filters.page ?? 0) + 1,
            pageSize: Number(filters.size ?? 15),
            total: query.data?.total ?? 0,
            showSizeChanger: false,
            onChange: (page) => setFilters((prev) => ({ ...prev, page: page - 1 })) }}
          onChange={(_p, _f, sorter) => {
            const s = Array.isArray(sorter) ? sorter[0] : sorter
            if (!s?.field) return
            setFilters((prev) => ({
              ...prev,
              sort: `${String(s.field)},${s.order === 'ascend' ? 'asc' : 'desc'}` }))
          }}
          scroll={{ x: 1500 }}
          locale={{ emptyText: '출고처가 없습니다.' }}
        />
      </Card>

      <Modal
        title={editing ? '출고처 수정' : '출고처 등록'}
        open={open}
        onCancel={() => { setOpen(false); setEditing(null) }}
        footer={null}
        width={560}
        destroyOnHidden
        centered
      >
        <Form
          form={editForm}
          labelCol={{ flex: '100px' }}
          wrapperCol={{ flex: 1 }}
          labelAlign="left"
          colon={false}
          onFinish={(values) => saveMut.mutate(values)}
        >
          <Form.Item name="name" label="출고처명" rules={[{ required: true, message: '출고처명을 입력하세요.' }]}>
            <Input placeholder="출고처명을 입력하세요" />
          </Form.Item>
          <Form.Item name="channel" label="채널">
            <Select allowClear placeholder="-채널-" options={channelOptions.map((v) => ({ value: v, label: v }))} />
          </Form.Item>
          <Form.Item name="category" label="분류">
            <Select allowClear placeholder="-분류-" options={categoryOptions.map((v) => ({ value: v, label: v }))} />
          </Form.Item>
          <Form.Item name="pcode" label="P코드">
            <Input />
          </Form.Item>
          <Form.Item name="salesperson" label="영업담당">
            <Input />
          </Form.Item>
          <Form.Item name="phone" label="전화">
            <Input />
          </Form.Item>
          <Form.Item name="managerName" label="담당자">
            <Input />
          </Form.Item>
          <Form.Item name="mobile" label="휴대폰">
            <Input placeholder="010-0000-0000" />
          </Form.Item>
          <Form.Item name="businessName" label="상호">
            <Input />
          </Form.Item>
          <Form.Item name="businessNumber" label="사업자번호">
            <Input placeholder="000-00-00000" />
          </Form.Item>
          <Form.Item name="bankAccount" label="계좌">
            <Input placeholder="은행 계좌번호 예금주" />
          </Form.Item>
          <Form.Item name="status" label="상태">
            <Select options={['사용', '미사용'].map((v) => ({ value: v, label: v }))} />
          </Form.Item>
          <Form.Item name="memo" label="비고">
            <Input.TextArea rows={2} />
          </Form.Item>
          <div className="sms-send-footer">
            <Button type="primary" htmlType="submit" loading={saveMut.isPending} icon={<EditOutlined />}>
              {editing ? '수정합니다' : '등록'}
            </Button>
            <Button onClick={() => { setOpen(false); setEditing(null) }}>취소</Button>
          </div>
        </Form>
      </Modal>

      <Modal
        title="비고"
        open={memoOpen}
        onCancel={() => { setMemoOpen(false); setMemoTarget(null) }}
        footer={null}
        width={420}
        destroyOnHidden
        centered
      >
        <Form form={memoForm} layout="vertical" onFinish={(values) => memoMut.mutate(String(values.memo ?? ''))}>
          <Form.Item name="memo" label={memoTarget?.name}>
            <Input.TextArea rows={4} placeholder="비고를 입력하세요" />
          </Form.Item>
          <div className="sms-send-footer">
            <Button type="primary" htmlType="submit" loading={memoMut.isPending}>저장</Button>
            <Button onClick={() => { setMemoOpen(false); setMemoTarget(null) }}>취소</Button>
          </div>
        </Form>
      </Modal>
    </div>
  )
}
