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

type AgencyRow = {
  id: number
  status?: string
  active?: boolean
  name?: string
  phone?: string
  fax?: string
  managerName?: string
  mobile?: string
  registeredDate?: string
  memo?: string
  agencyType?: string
  address?: string
}

type AgencyResult = {
  total: number
  list: AgencyRow[]
  counts?: Record<string, number>
}

const initial = { page: 0, size: 10 } as Record<string, unknown>

export default function SettingAgencyPage() {
  const qc = useQueryClient()
  const [form] = Form.useForm()
  const [editForm] = Form.useForm()
  const [memoForm] = Form.useForm()
  const [filters, setFilters] = useState<Record<string, unknown>>(initial)
  const [selected, setSelected] = useState<number[]>([])
  const [open, setOpen] = useState(false)
  const [editing, setEditing] = useState<AgencyRow | null>(null)
  const [memoOpen, setMemoOpen] = useState(false)
  const [memoTarget, setMemoTarget] = useState<AgencyRow | null>(null)

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

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

  const saveMut = useMutation({
    mutationFn: async (values: Record<string, unknown>) => {
      const payload = {
        name: values.name,
        phone: values.phone,
        fax: values.fax,
        managerName: values.managerName,
        mobile: values.mobile,
        memo: values.memo,
        status: values.status || '사용',
        agencyType: values.agencyType || '대리점',
        address: values.address }
      if (editing?.id) {
        const { data } = await client.put(`${apiPrefix()}/homes/agencies/${editing.id}`, payload)
        return unwrap(data as ApiResponse)
      }
      const { data } = await client.post(`${apiPrefix()}/homes/agencies`, payload)
      return unwrap(data as ApiResponse)
    },
    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()}/homes/agencies/status`, { ids: selected, status })
      return unwrap(data as ApiResponse<{ updated: number }>)
    },
    onSuccess: (data, status) => {
      message.success(`${data.updated}건을 ${status} 처리했습니다.`)
      refresh()
    },
    onError: (e: Error) => message.error(e.message) })

  const memoMut = useMutation({
    mutationFn: async (memo: string) => {
      const { data } = await client.put(`${apiPrefix()}/homes/agencies/${memoTarget!.id}`, {
        name: memoTarget!.name,
        phone: memoTarget!.phone,
        fax: memoTarget!.fax,
        managerName: memoTarget!.managerName,
        mobile: memoTarget!.mobile,
        status: memoTarget!.status || '사용',
        memo })
      return unwrap(data as ApiResponse)
    },
    onSuccess: () => {
      message.success('비고를 저장했습니다.')
      setMemoOpen(false)
      setMemoTarget(null)
      memoForm.resetFields()
      refresh()
    },
    onError: (e: Error) => message.error(e.message) })

  const onSearch = (values: Record<string, unknown>) => {
    setFilters({
      ...initial,
      status: values.status || undefined,
      q: values.q || undefined,
      page: 0,
      size: Number(values.size ?? filters.size ?? 10) })
  }

  const onReset = () => {
    form.resetFields()
    form.setFieldsValue({ size: 10 })
    setFilters(initial)
  }

  const openCreate = () => {
    setEditing(null)
    editForm.setFieldsValue({
      name: undefined,
      phone: undefined,
      fax: undefined,
      managerName: undefined,
      mobile: undefined,
      memo: undefined,
      status: '사용',
      agencyType: '대리점' })
    setOpen(true)
  }

  const openEdit = (row: AgencyRow) => {
    setEditing(row)
    editForm.setFieldsValue({
      name: row.name,
      phone: row.phone,
      fax: row.fax,
      managerName: row.managerName,
      mobile: row.mobile,
      memo: row.memo,
      status: row.status || '사용',
      agencyType: row.agencyType || '대리점',
      address: row.address })
    setOpen(true)
  }

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

  const download = async () => {
    try {
      const { data } = await client.get(`${apiPrefix()}/homes/agencies/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 requireSelected = (status: '사용' | '정지') => {
    if (!selected.length) {
      message.warning('거래처를 선택하세요.')
      return
    }
    statusMut.mutate(status)
  }

  const columns = useMemo(
    () => [
      {
        title: '상태',
        dataIndex: 'status',
        width: 70,
        align: 'center' as const,
        render: (v: string) => <span className={v === '정지' ? 'farebox-cancelled' : ''}>{v || '사용'}</span> },
      {
        title: '업체명',
        dataIndex: 'name',
        width: 160,
        ellipsis: true,
        sorter: (a: AgencyRow, b: AgencyRow) => String(a.name || '').localeCompare(String(b.name || ''), 'ko') },
      { title: '전화', dataIndex: 'phone', width: 120, align: 'center' as const, render: (v?: string) => v || '' },
      { title: '팩스', dataIndex: 'fax', width: 120, align: 'center' as const, render: (v?: string) => v || '' },
      { title: '담당자', dataIndex: 'managerName', width: 90, align: 'center' as const, render: (v?: string) => v || '' },
      { title: '휴대폰', dataIndex: 'mobile', width: 120, align: 'center' as const, render: (v?: string) => v || '' },
      {
        title: '등록일',
        dataIndex: 'registeredDate',
        width: 110,
        align: 'center' as const,
        sorter: (a: AgencyRow, b: AgencyRow) =>
          String(a.registeredDate || '').localeCompare(String(b.registeredDate || '')) },
      {
        title: '비고',
        key: 'memo',
        width: 60,
        align: 'center' as const,
        render: (_: unknown, row: AgencyRow) => (
          <Button
            type="text"
            size="small"
            icon={<MailOutlined style={{ color: row.memo ? 'var(--primary)' : '#94a3b8' }} />}
            onClick={() => openMemo(row)}
          />
        ) },
      {
        title: '관리',
        key: 'manage',
        width: 64,
        align: 'center' as const,
        fixed: 'right' as const,
        render: (_: unknown, row: AgencyRow) => (
          <Button
            type="primary"
            size="small"
            className="agency-manage-btn"
            icon={<EditOutlined />}
            onClick={() => openEdit(row)}
          />
        ) },
    ],
    [],
  )

  return (
    <div className="stock-page agency-manage-page">
      <div className="stock-title">
        <div>
          <h2>
            <SettingOutlined className="product-title-icon" />
            거래처관리
          </h2>
          <p>거래처를 등록 혹은 관리하실 수 있습니다.</p>
        </div>
        <Space className="stock-title-actions" wrap>
          <Button
            className="farebox-gray-btn"
            disabled={!selected.length}
            loading={statusMut.isPending}
            onClick={() => requireSelected('사용')}
          >
            사용
          </Button>
          <Button
            className="farebox-gray-btn"
            disabled={!selected.length}
            loading={statusMut.isPending}
            onClick={() => requireSelected('정지')}
          >
            정지
          </Button>
          <Button className="agency-register-btn" type="primary" icon={<PlusSquareOutlined />} onClick={openCreate}>
            거래처 등록
          </Button>
        </Space>
      </div>

      <Card className="stock-filter-card" size="small">
        <Form
          form={form}
          layout="inline"
          className="farebox-filter"
          initialValues={{ size: 10 }}
          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="q">
              <Input className="w-180" allowClear placeholder="업체명/담당자" />
            </Form.Item>
            <Form.Item>
              <Space>
                <Button type="primary" htmlType="submit" icon={<SearchOutlined />}>
                  검색
                </Button>
                <Button icon={<ReloadOutlined />} onClick={onReset}>
                  초기화
                </Button>
              </Space>
            </Form.Item>
            <Form.Item name="size" className="farebox-size">
              <Select
                className="w-150"
                options={[10, 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="farebox-table-toolbar">
          <Typography.Text>
            목록 <b>{query.data?.total ?? 0}</b>
          </Typography.Text>
          <Button type="link" icon={<DownloadOutlined />} 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 ?? 10),
            total: query.data?.total ?? 0,
            showSizeChanger: false,
            onChange: (page) => setFilters((prev) => ({ ...prev, page: page - 1 })) }}
          scroll={{ x: 1100 }}
          locale={{ emptyText: '등록된 거래처가 없습니다.' }}
        />
      </Card>

      <Modal
        title={editing ? '거래처 수정' : '거래처 등록'}
        open={open}
        onCancel={() => {
          setOpen(false)
          setEditing(null)
        }}
        footer={null}
        width={520}
        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="phone" label="전화">
            <Input placeholder="02-0000-0000" />
          </Form.Item>
          <Form.Item name="fax" 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="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
              className="agency-submit-btn"
              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} onFinish={(v) => memoMut.mutate(String(v.memo || ''))}>
          <Form.Item name="memo" style={{ marginBottom: 16 }}>
            <Input.TextArea rows={4} placeholder="비고를 입력하세요" />
          </Form.Item>
          <div className="sms-send-footer">
            <Button className="agency-submit-btn" type="primary" htmlType="submit" loading={memoMut.isPending}>
              저장
            </Button>
            <Button
              onClick={() => {
                setMemoOpen(false)
                setMemoTarget(null)
              }}
            >
              취소
            </Button>
          </div>
        </Form>
      </Modal>
    </div>
  )
}
