import { useMemo, useState } from 'react'
import { Link } from 'react-router-dom'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import { Area, Column } from '@ant-design/plots'
import { Card, Form, Input, Modal, Spin, Tabs, message } from 'antd'
import {
  BookOutlined,
  CalendarOutlined,
  CustomerServiceOutlined,
  EditOutlined,
  LeftOutlined,
  RightOutlined,
  ScheduleOutlined,
  TeamOutlined } from '@ant-design/icons'
import client, { apiPrefix, unwrap, type ApiResponse } from '../../api/client'
import { homeAccentColors } from '../../theme'
import { useTheme } from '../../themeContext'
import { money } from './homesShared'

type SparkBlock = {
  open?: number
  today?: number
  total?: number
  monthNew?: number
  monthAmount?: number
  settleMonth?: number
  spark?: number[]
}

type ChartPanel = {
  title?: string
  label?: string
  offset?: number
  apply?: number
  accept?: number
  done?: number
  cancel?: number
  settleAmount?: number
  count?: number
  daily?: { day: number; value: number }[]
}

type StatusBlock = {
  total?: number
  items?: Record<string, number>
}

type Postit = {
  slot: number
  title?: string
  contents?: string
  authorName?: string
  noteDate?: string
}

type Dash = {
  pending?: SparkBlock
  booking?: SparkBlock
  customer?: SparkBlock
  abook?: SparkBlock
  contractTotal?: number
  customerTotal?: number
  postits?: Postit[]
  internet?: ChartPanel
  home?: ChartPanel
  internetStatus?: StatusBlock
  homeStatus?: StatusBlock
  notices?: { id: number; title?: string; createdDate?: string }[]
  questions?: { id: number; title?: string; createdDate?: string }[]
  csPhone?: string
}

function Wave({ color }: { color: string }) {
  return (
    <svg className="home-wave" viewBox="0 0 200 42" preserveAspectRatio="none" aria-hidden>
      <path
        d="M0 28 C 30 8, 50 38, 80 22 S 130 4, 160 24 S 190 36, 200 18 L200 42 L0 42 Z"
        fill={color}
        opacity="0.35"
      />
      <path
        d="M0 32 C 40 18, 70 36, 100 26 S 150 12, 180 28 S 195 34, 200 26 L200 42 L0 42 Z"
        fill={color}
        opacity="0.55"
      />
    </svg>
  )
}

function MiniBars({ values, color }: { values: number[]; color: string }) {
  const max = Math.max(1, ...values)
  return (
    <div className="home-mini-bars" aria-hidden>
      {values.map((v, i) => (
        <span key={i} style={{ height: `${Math.max(12, (v / max) * 100)}%`, background: color }} />
      ))}
    </div>
  )
}

export default function HomeDashboardPage() {
  const { theme } = useTheme()
  const accents = useMemo(() => homeAccentColors(theme), [theme])
  const qc = useQueryClient()
  const [offset, setOffset] = useState(0)
  const [period, setPeriod] = useState('day')
  const [editSlot, setEditSlot] = useState<Postit | null>(null)
  const [form] = Form.useForm()

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

  const savePostit = useMutation({
    mutationFn: async (values: { contents: string }) => {
      if (!editSlot) return
      const { data } = await client.put(`${apiPrefix()}/homes/dashboard/postits/${editSlot.slot}`, {
        contents: values.contents,
        authorName: localStorage.getItem('userName') || '홍길동' })
      return unwrap(data)
    },
    onSuccess: () => {
      message.success('저장했습니다.')
      setEditSlot(null)
      qc.invalidateQueries({ queryKey: ['homes-dashboard'] })
    },
    onError: (e: Error) => message.error(e.message) })

  if (query.isLoading) {
    return (
      <div className="home-loading">
        <Spin size="large" />
      </div>
    )
  }

  const d = query.data || {}
  const pending = d.pending || {}
  const booking = d.booking || {}
  const customer = d.customer || {}
  const abook = d.abook || {}
  const internet = d.internet || {}
  const home = d.home || {}
  const internetStatus = d.internetStatus || {}
  const homeStatus = d.homeStatus || {}

  const columnCfg = (daily: { day: number; value: number }[] | undefined, fill: string) => ({
    data: daily || [],
    xField: 'day',
    yField: 'value',
    height: 180,
    autoFit: true,
    color: fill,
    columnStyle: { radius: [3, 3, 0, 0] },
    xAxis: { label: { style: { fill: accents.plot.axisLabelFill, fontSize: 10 } }, line: null, tickLine: null },
    yAxis: {
      label: { style: { fill: accents.plot.axisLabelFill, fontSize: 10 } },
      grid: { line: { style: { stroke: accents.plot.gridStroke } } } },
    tooltip: { title: (v: number) => `${v}일` } })

  const areaCfg = (daily: { day: number; value: number }[] | undefined, stroke: string, fill: string) => ({
    data: daily || [],
    xField: 'day',
    yField: 'value',
    height: 180,
    autoFit: true,
    smooth: true,
    color: stroke,
    areaStyle: { fill },
    line: { color: stroke, size: 2 },
    xAxis: { label: { style: { fill: accents.plot.axisLabelFill, fontSize: 10 } }, line: null, tickLine: null },
    yAxis: {
      label: { style: { fill: accents.plot.axisLabelFill, fontSize: 10 } },
      grid: { line: { style: { stroke: accents.plot.gridStroke } } } } })

  return (
    <div className="home-dashboard">
      <div className="home-top-row">
        <Card className="home-card" size="small">
          <div className="home-stock-split">
            <Link to="/care/pending/pending" className="home-stock-block">
              <div className="home-stock-head">
                <div>
                  <div className="home-card-title">
                    <CalendarOutlined /> 일정관리
                  </div>
                  <div className="home-stock-total">
                    {pending.open ?? 0} <span className="home-stock-hint">/ {pending.total ?? 0}</span>
                  </div>
                  <div className="home-stock-hint">오늘 약속 {pending.today ?? 0}건</div>
                </div>
                <MiniBars values={pending.spark || [2, 3, 4, 3, 5, 4]} color={accents.sparkPhone} />
              </div>
              <div className="home-stock-meta">
                <span>
                  미결 <b>{pending.open ?? 0}</b>
                </span>
                <span>
                  오늘 <b>{pending.today ?? 0}</b>
                </span>
              </div>
              <Wave color={accents.sparkPhone} />
            </Link>
            <Link to="/care/booking/booking" className="home-stock-block">
              <div className="home-stock-head">
                <div>
                  <div className="home-card-title">
                    <ScheduleOutlined /> 예약관리
                  </div>
                  <div className="home-stock-total">
                    {booking.open ?? 0} <span className="home-stock-hint">/ {booking.total ?? 0}</span>
                  </div>
                  <div className="home-stock-hint">접수 대기 현황</div>
                </div>
                <MiniBars values={booking.spark || [1, 2, 2, 3, 2, 1]} color={accents.sparkUsim} />
              </div>
              <div className="home-stock-meta">
                <span>
                  접수 <b>{booking.open ?? 0}</b>
                </span>
                <span>
                  전체 <b>{booking.total ?? 0}</b>
                </span>
              </div>
              <Wave color={accents.sparkUsim} />
            </Link>
          </div>
        </Card>

        <Card className="home-card" size="small">
          <div className="home-status-split">
            <Link to="/care/customer/customer" className="home-status-block">
              <div className="home-status-top">
                <div>
                  <div className="home-card-title">등록고객</div>
                  <div className="home-status-value">
                    {customer.total ?? d.customerTotal ?? 0}명
                  </div>
                  <div className="home-stock-hint">이달 신규 {customer.monthNew ?? 0}</div>
                </div>
                <TeamOutlined className="home-status-icon teal" />
              </div>
              <Wave color={accents.waveOut} />
            </Link>
            <Link to="/care/abooks/abooks-mon" className="home-status-block">
              <div className="home-status-top">
                <div>
                  <div className="home-card-title">이달장부</div>
                  <div className="home-status-value">{money(abook.monthAmount)}</div>
                  <div className="home-stock-hint">정산 {money(abook.settleMonth)}</div>
                </div>
                <BookOutlined className="home-status-icon purple" />
              </div>
              <Wave color={accents.waveFare} />
            </Link>
          </div>
        </Card>
      </div>

      <div className="home-postit-row">
        {(d.postits || []).map((p) => (
          <div key={p.slot} className="home-postit">
            <div className="home-postit-head">
              <span>{p.title || `포스트잇 #${p.slot}`}</span>
              <button
                type="button"
                aria-label="수정"
                onClick={() => {
                  setEditSlot(p)
                  form.setFieldsValue({ contents: p.contents })
                }}
              >
                <EditOutlined />
              </button>
            </div>
            <div className="home-postit-body">{p.contents || ''}</div>
            <div className="home-postit-foot">
              <span>by {p.authorName || '-'}</span>
              <span>{p.noteDate || ''}</span>
            </div>
          </div>
        ))}
      </div>

      <div className="home-chart-row">
        <Card
          className="home-card"
          size="small"
          title={
            <div className="home-chart-head">
              <span>
                <button type="button" className="home-month-nav" onClick={() => setOffset((o) => o + 1)}>
                  <LeftOutlined />
                </button>
                인터넷접수 (영업기준)
                <button
                  type="button"
                  className="home-month-nav"
                  onClick={() => setOffset((o) => Math.max(0, o - 1))}
                >
                  <RightOutlined />
                </button>
              </span>
              <Tabs
                size="small"
                activeKey={period}
                onChange={setPeriod}
                items={[
                  { key: 'day', label: '매일' },
                  { key: 'month', label: '매달' },
                  { key: 'total', label: '전체' },
                ]}
              />
            </div>
          }
        >
          <div className="home-chart-sub">
            <span>{internet.label}</span>
            <span className="muted">계약 {internet.count ?? 0}건</span>
          </div>
          <div className="home-chart-stats four">
            <div>
              <em>신청</em>
              <b>{internet.apply ?? 0}</b>
            </div>
            <div>
              <em>접수</em>
              <b>{internet.accept ?? 0}</b>
            </div>
            <div>
              <em>완료</em>
              <b>{internet.done ?? 0}</b>
            </div>
            <div>
              <em>정산금액</em>
              <b>{money(internet.settleAmount)}</b>
            </div>
          </div>
          <div className="home-chart-plot">
            <Column {...columnCfg(internet.daily, accents.columnFill)} />
          </div>
          <div className="home-cat-block">
            <div className="home-cat-total">인터넷현황 {internetStatus.total ?? 0}</div>
            <div className="home-cat-grid">
              {Object.entries(internetStatus.items || {}).map(([k, v]) => (
                <div key={k} className="home-cat-item">
                  <MiniBars values={[2, 3, 4, 3, Number(v) || 1, 2]} color={accents.sparkPhone} />
                  <span>{k}</span>
                  <b>{v}</b>
                </div>
              ))}
            </div>
          </div>
        </Card>

        <Card
          className="home-card"
          size="small"
          title={
            <div className="home-chart-head">
              <span>홈렌탈접수 (영업기준)</span>
              <Tabs
                size="small"
                activeKey={period}
                onChange={setPeriod}
                items={[
                  { key: 'day', label: '매일' },
                  { key: 'month', label: '매달' },
                  { key: 'total', label: '전체' },
                ]}
              />
            </div>
          }
        >
          <div className="home-chart-sub">
            <span>{home.label}</span>
            <span className="muted">계약 {home.count ?? 0}건</span>
          </div>
          <div className="home-chart-stats four">
            <div>
              <em>신청</em>
              <b>{home.apply ?? 0}</b>
            </div>
            <div>
              <em>접수</em>
              <b>{home.accept ?? 0}</b>
            </div>
            <div>
              <em>완료</em>
              <b>{home.done ?? 0}</b>
            </div>
            <div>
              <em>정산금액</em>
              <b>{money(home.settleAmount)}</b>
            </div>
          </div>
          <div className="home-chart-plot">
            <Area
              {...areaCfg(
                home.daily,
                accents.columnFill,
                theme === 'light' ? 'rgba(37,99,235,0.22)' : 'rgba(122,162,247,0.28)',
              )}
            />
          </div>
          <div className="home-cat-block">
            <div className="home-cat-total">홈렌탈현황 {homeStatus.total ?? 0}</div>
            <div className="home-cat-grid">
              {Object.entries(homeStatus.items || {}).map(([k, v]) => (
                <div key={k} className="home-cat-item">
                  <MiniBars values={[1, 2, 3, Number(v) || 1, 2, 3]} color={accents.areaStroke} />
                  <span>{k}</span>
                  <b>{v}</b>
                </div>
              ))}
            </div>
          </div>
        </Card>
      </div>

      <div className="home-bottom-row">
        <Card
          className="home-card home-list-card"
          size="small"
          title={
            <Link to="/care/cs/notice">
              공지사항
            </Link>
          }
        >
          <ul className="home-list notice">
            {(d.notices || []).length === 0 ? (
              <li className="empty">등록된 공지가 없습니다.</li>
            ) : (
              (d.notices || []).map((n) => (
                <li key={n.id}>
                  <Link to="/care/cs/notice">{n.title}</Link>
                  <span>{n.createdDate}</span>
                </li>
              ))
            )}
          </ul>
        </Card>
        <Card
          className="home-card home-list-card"
          size="small"
          title={<Link to="/care/cs/question">사용문의</Link>}
        >
          <ul className="home-list notice">
            {(d.questions || []).length === 0 ? (
              <li className="empty">등록된 문의가 없습니다.</li>
            ) : (
              (d.questions || []).map((q) => (
                <li key={q.id}>
                  <Link to="/care/cs/question">{q.title}</Link>
                  <span>{q.createdDate}</span>
                </li>
              ))
            )}
          </ul>
        </Card>
        <Card
          className="home-card home-cs-card"
          size="small"
          title={
            <span>
              <CustomerServiceOutlined /> 고객센터
            </span>
          }
        >
          <div className="home-cs-phone">{d.csPhone || '0000-0000'}</div>
        </Card>
      </div>

      <Modal
        title={editSlot ? `포스트잇 #${editSlot.slot}` : '포스트잇'}
        open={Boolean(editSlot)}
        onCancel={() => setEditSlot(null)}
        onOk={() => form.submit()}
        confirmLoading={savePostit.isPending}
        destroyOnHidden
      >
        <Form form={form} layout="vertical" onFinish={(v) => savePostit.mutate(v)}>
          <Form.Item name="contents" label="내용" rules={[{ required: true, message: '내용을 입력하세요' }]}>
            <Input.TextArea rows={4} maxLength={200} showCount />
          </Form.Item>
        </Form>
      </Modal>
    </div>
  )
}
