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 {
  QuestionCircleOutlined,
  ReloadOutlined,
  SearchOutlined } from '@ant-design/icons'
import client, { apiPrefix, unwrap, type ApiResponse } from '../../api/client'

type NoticeRow = {
  id: number
  no?: number
  title?: string
  views?: number
  createdDate?: string
  authorName?: string
  contents?: string
}

type NoticeResult = {
  total: number
  list: NoticeRow[]
}

const initial = { page: 0, size: 10, searchType: '제목', sort: 'id,desc' } as Record<string, unknown>

export default function CsNoticePage() {
  const qc = useQueryClient()
  const [form] = Form.useForm()
  const [filters, setFilters] = useState<Record<string, unknown>>(initial)
  const [detail, setDetail] = useState<NoticeRow | null>(null)

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

  const openDetail = useMutation({
    mutationFn: async (id: number) => {
      const { data } = await client.get<ApiResponse<NoticeRow>>(`${apiPrefix()}/homes/notices/${id}`)
      return unwrap(data)
    },
    onSuccess: (row) => {
      setDetail(row)
      qc.invalidateQueries({ queryKey: ['homes-notices'] })
    },
    onError: (e: Error) => message.error(e.message) })

  const onSearch = (values: Record<string, unknown>) => {
    setFilters({
      ...initial,
      searchType: values.searchType || '제목',
      keyword: values.keyword || undefined,
      page: 0,
      size: Number(values.size ?? filters.size ?? 10),
      sort: filters.sort })
  }

  const onReset = () => {
    form.resetFields()
    form.setFieldsValue({ searchType: '제목', size: 10 })
    setFilters(initial)
  }

  const columns = useMemo(
    () => [
      {
        title: '번호',
        dataIndex: 'no',
        width: 90,
        align: 'center' as const,
        sorter: true },
      {
        title: '제목',
        dataIndex: 'title',
        ellipsis: true,
        render: (v: string, row: NoticeRow) => (
          <Button type="link" className="cs-notice-title" onClick={() => openDetail.mutate(row.id)}>
            {v}
          </Button>
        ) },
      {
        title: '조회',
        dataIndex: 'views',
        width: 90,
        align: 'center' as const,
        sorter: true,
        render: (v?: number) => (v == null ? 0 : Number(v).toLocaleString()) },
      {
        title: '등록일',
        dataIndex: 'createdDate',
        width: 120,
        align: 'center' as const,
        sorter: true },
    ],
    [],
  )

  return (
    <div className="stock-page cs-notice-page homes-cs-notice-page">
      <div className="stock-title">
        <div>
          <h2>
            <QuestionCircleOutlined className="product-title-icon" />
            공지사항
          </h2>
          <p>프로그램 사용에 대한 공지사항이나 업데이트를 알려드립니다.</p>
        </div>
      </div>

      <Card className="stock-filter-card" size="small">
        <Form
          form={form}
          layout="inline"
          className="farebox-filter"
          initialValues={{ searchType: '제목', size: 10 }}
          onFinish={onSearch}
        >
          <div className="farebox-filter-row">
            <Form.Item name="searchType">
              <Select className="w-110" options={['제목', '내용', '작성자'].map((v) => ({ value: v, label: v }))} />
            </Form.Item>
            <Form.Item name="keyword">
              <Input className="w-230" allowClear />
            </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>
        </div>
        <CareTable
          size="small"
          loading={query.isLoading}
          rowKey="id"
          dataSource={query.data?.list}
          columns={columns}
          bordered
          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 })) }}
          onChange={(_p, _f, sorter) => {
            const s = Array.isArray(sorter) ? sorter[0] : sorter
            if (!s?.field || !s.order) return
            setFilters((prev) => ({
              ...prev,
              sort: `${String(s.field)},${s.order === 'ascend' ? 'asc' : 'desc'}` }))
          }}
          locale={{ emptyText: '등록된 공지사항이 없습니다.' }}
        />
      </Card>

      <Modal
        title="공지사항"
        open={Boolean(detail)}
        onCancel={() => setDetail(null)}
        footer={<Button onClick={() => setDetail(null)}>닫기</Button>}
        width={640}
        destroyOnHidden
        centered
      >
        {detail ? (
          <div>
            <Typography.Title level={5} style={{ marginTop: 0 }}>
              {detail.title}
            </Typography.Title>
            <div className="cs-notice-meta">
              <span>조회 {detail.views ?? 0}</span>
              <span>등록일 {detail.createdDate || '-'}</span>
            </div>
            <div className="cs-notice-body">
              {(detail.contents || '')
                .split('\n')
                .map((line, idx) => (
                  <p key={idx}>{line || '\u00A0'}</p>
                ))}
            </div>
          </div>
        ) : null}
      </Modal>
    </div>
  )
}
