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

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

type BoardData = {
  total: number
  list: BoardRow[]
}

type Props = {
  code: string
  title: string
}

export default function InternalBoardPage({ code, title }: Props) {
  const qc = useQueryClient()
  const [form] = Form.useForm()
  const [editForm] = Form.useForm()
  const [open, setOpen] = useState(false)
  const [editing, setEditing] = useState<BoardRow | null>(null)
  const [detail, setDetail] = useState<BoardRow | null>(null)
  const [filters, setFilters] = useState<Record<string, unknown>>({
    code,
    searchType: '제목',
    page: 0,
    size: 15,
    sort: 'createdAt,desc' })

  const query = useQuery({
    queryKey: ['internal-board', code, filters],
    queryFn: async () => {
      const { data } = await client.get<ApiResponse<BoardData>>(`${apiPrefix()}/bbs/search`, {
        params: { ...filters, code } })
      return unwrap(data)
    } })

  const refresh = () => qc.invalidateQueries({ queryKey: ['internal-board', code] })

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

  const openDetail = useMutation({
    mutationFn: async (id: number) => {
      const { data } = await client.get<ApiResponse<BoardRow>>(`${apiPrefix()}/bbs/${id}`)
      return unwrap(data)
    },
    onSuccess: (row) => {
      setDetail(row)
      refresh()
    },
    onError: (e: Error) => message.error(e.message) })

  const onSearch = (values: Record<string, unknown>) => {
    setFilters((prev) => ({
      ...prev,
      code,
      searchType: values.searchType || '제목',
      keyword: values.keyword,
      page: 0,
      size: Number(values.size ?? prev.size ?? 15) }))
  }

  const onReset = () => {
    form.setFieldsValue({ searchType: '제목', keyword: undefined, size: 15 })
    setFilters({ code, searchType: '제목', page: 0, size: 15, sort: 'createdAt,desc' })
  }

  const openCreate = () => {
    setEditing(null)
    editForm.resetFields()
    setOpen(true)
  }

  const openEdit = (row: BoardRow) => {
    setEditing(row)
    editForm.setFieldsValue({ title: row.title, contents: row.contents })
    setOpen(true)
  }

  const columns = useMemo(() => [
    {
      title: '번호',
      dataIndex: 'no',
      width: 90,
      align: 'center' as const,
      sorter: true },
    {
      title: '제목',
      dataIndex: 'title',
      ellipsis: true,
      render: (v: string, row: BoardRow) => (
        <Button type="link" className="cs-notice-title" onClick={() => openDetail.mutate(row.id)}>
          {v}
          {row.commentCount && row.commentCount > 0 ? (
            <span className="bbs-comment-badge">{row.commentCount}</span>
          ) : null}
        </Button>
      ) },
    {
      title: '직원',
      dataIndex: 'authorName',
      width: 110,
      align: 'center' as const,
      sorter: true },
    {
      title: '조회',
      dataIndex: 'views',
      width: 90,
      align: 'center' as const,
      sorter: true },
    {
      title: '등록일',
      dataIndex: 'createdDate',
      width: 120,
      align: 'center' as const,
      sorter: true },
  ], [])

  return (
    <div className="stock-page cs-notice-page internal-board-page">
      <div className="stock-title">
        <div>
          <h2><UnorderedListOutlined style={{ marginRight: 8 }} />{title}</h2>
        </div>
        <Button type="primary" icon={<EditOutlined />} onClick={openCreate}>게시물 등록</Button>
      </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="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 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>
        </div>
        <CareTable
          size="small"
          loading={query.isLoading}
          rowKey="id"
          dataSource={query.data?.list}
          columns={columns}
          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
            const fieldMap: Record<string, string> = {
              no: 'id',
              authorName: 'authorName',
              views: 'views',
              createdDate: 'createdAt',
              title: 'title' }
            const field = fieldMap[String(s.field)] || String(s.field)
            setFilters((prev) => ({
              ...prev,
              sort: `${field},${s.order === 'ascend' ? 'asc' : 'desc'}`,
              page: 0 }))
          }}
          locale={{ emptyText: '등록되어 있는 게시물이 없습니다.' }}
        />
      </Card>

      <Modal
        title={editing ? '게시물 수정' : '게시물 등록'}
        open={open}
        onCancel={() => { setOpen(false); setEditing(null) }}
        footer={null}
        destroyOnClose
        width={720}
      >
        <Form
          form={editForm}
          layout="vertical"
          onFinish={(values) => saveMut.mutate(values)}
        >
          <Form.Item name="title" label="제목" rules={[{ required: true, message: '제목을 입력하세요.' }]}>
            <Input maxLength={200} />
          </Form.Item>
          <Form.Item name="contents" label="내용" rules={[{ required: true, message: '내용을 입력하세요.' }]}>
            <Input.TextArea rows={10} />
          </Form.Item>
          <div className="bbs-write-actions">
            <Button type="primary" htmlType="submit" loading={saveMut.isPending}>
              {editing ? '수정합니다' : '등록'}
            </Button>
            <Button onClick={() => { setOpen(false); setEditing(null) }}>취소</Button>
          </div>
        </Form>
      </Modal>

      <Modal
        title={detail?.title || title}
        open={!!detail}
        onCancel={() => setDetail(null)}
        footer={
          <Space>
            <Button onClick={() => { if (detail) openEdit(detail); setDetail(null) }}>수정</Button>
            <Button onClick={() => setDetail(null)}>닫기</Button>
          </Space>
        }
        width={720}
        destroyOnClose
      >
        <div className="cs-notice-meta">
          <span>직원 {detail?.authorName || '-'}</span>
          <span>등록일 {detail?.createdDate || '-'}</span>
          <span>조회 {detail?.views ?? 0}</span>
        </div>
        <div
          className="cs-notice-body"
          style={{ whiteSpace: 'pre-wrap' }}
          dangerouslySetInnerHTML={{
            __html: detail?.contents?.includes('<') ? (detail.contents || '') : (detail?.contents || '-').replace(/\n/g, '<br/>') }}
        />
      </Modal>
    </div>
  )
}

export function CompanyBoardPage() {
  return <InternalBoardPage code="company" title="사내게시판" />
}

export function DataBoardPage() {
  return <InternalBoardPage code="grouppds" title="자료게시판" />
}
