import { useEffect, useRef, useState } from 'react'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import {
  Button, Card, Checkbox, Form, Input, InputNumber, Radio, Select, Space, Tabs, Typography, message } from 'antd'
import CareTable from '../../components/CareTable'
import { PlusOutlined, SettingOutlined } from '@ant-design/icons'
import client, { apiPrefix, unwrap, type ApiResponse } from '../../api/client'

type CompanyInfo = {
  name?: string
  managerName?: string
  mobile?: string
  businessName?: string
  businessNumber?: string
  ceo?: string
  bizType?: string
  bizItem?: string
  address?: string
}

type AccessIps = {
  enabled?: boolean
  ips?: string[]
}

type Masking = {
  enabled?: boolean
  name?: boolean
  phone?: boolean
  rrn?: boolean
  address?: boolean
}

type StockSetting = {
  duplicateSerialCheck?: boolean
  allowNegative?: boolean
  autoRecallDays?: number
}

type OpenSetting = {
  requireUsim?: boolean
  requirePhone?: boolean
  defaultOpenHow?: string
  autoSettle?: boolean
}

type Preference = {
  company?: CompanyInfo
  accessIps?: AccessIps
  masking?: Masking
  outCategories?: string[]
  stock?: StockSetting
  open?: OpenSetting
}

const TAB_KEYS = [
  { key: 'company', label: '사업자정보' },
  { key: 'accessIp', label: '접속아이피' },
  { key: 'masking', label: '개인정보마스킹' },
  { key: 'outCategory', label: '출고처분류' },
  { key: 'stock', label: '재고설정' },
  { key: 'open', label: '개통설정' },
] as const

type TabKey = (typeof TAB_KEYS)[number]['key']

const splitPhone = (mobile?: string) => {
  const digits = String(mobile || '').replace(/\D/g, '')
  if (digits.length >= 10) {
    return {
      p1: digits.slice(0, 3),
      p2: digits.slice(3, 7),
      p3: digits.slice(7, 11) }
  }
  const parts = String(mobile || '').split('-')
  return { p1: parts[0] || '010', p2: parts[1] || '', p3: parts[2] || '' }
}

const splitBizNo = (no?: string) => {
  const parts = String(no || '').split('-')
  if (parts.length >= 3) return { b1: parts[0], b2: parts[1], b3: parts[2] }
  const digits = String(no || '').replace(/\D/g, '')
  return {
    b1: digits.slice(0, 3),
    b2: digits.slice(3, 5),
    b3: digits.slice(5, 10) }
}

function SectionHead({ title, desc }: { title: string; desc: string }) {
  return (
    <div className="pref-section-head">
      <h3>{title}</h3>
      <p>{desc}</p>
    </div>
  )
}

export default function PreferencePage() {
  const qc = useQueryClient()
  const [tab, setTab] = useState<TabKey>('company')
  const [companyForm] = Form.useForm()
  const [maskForm] = Form.useForm()
  const [stockForm] = Form.useForm()
  const [openForm] = Form.useForm()
  const [ipInput, setIpInput] = useState('')
  const [categoryInput, setCategoryInput] = useState('')
  const [localIps, setLocalIps] = useState<string[]>([])
  const [ipEnabled, setIpEnabled] = useState(false)
  const [categories, setCategories] = useState<string[]>([])
  const sectionRefs = useRef<Record<TabKey, HTMLDivElement | null>>({
    company: null,
    accessIp: null,
    masking: null,
    outCategory: null,
    stock: null,
    open: null })

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

  useEffect(() => {
    if (!query.data) return
    const c = query.data.company || {}
    const phone = splitPhone(c.mobile)
    const biz = splitBizNo(c.businessNumber)
    companyForm.setFieldsValue({
      name: c.name,
      managerName: c.managerName,
      phone1: phone.p1 || '010',
      phone2: phone.p2,
      phone3: phone.p3,
      businessName: c.businessName,
      biz1: biz.b1,
      biz2: biz.b2,
      biz3: biz.b3,
      ceo: c.ceo,
      bizType: c.bizType,
      bizItem: c.bizItem,
      address: c.address })
    setLocalIps(query.data.accessIps?.ips || [])
    setIpEnabled(!!query.data.accessIps?.enabled)
    maskForm.setFieldsValue(query.data.masking || {})
    setCategories(query.data.outCategories || [])
    stockForm.setFieldsValue(query.data.stock || {})
    openForm.setFieldsValue(query.data.open || {})
  }, [query.data, companyForm, maskForm, stockForm, openForm])

  const save = useMutation({
    mutationFn: async (patch: Preference) => {
      const { data } = await client.put<ApiResponse<Preference>>(`${apiPrefix()}/settings/preference`, patch)
      return unwrap(data)
    },
    onSuccess: (data) => {
      qc.setQueryData(['preference'], data)
      message.success('적용했습니다.')
    },
    onError: (e: Error) => message.error(e.message) })

  const onTabChange = (key: string) => {
    const k = key as TabKey
    setTab(k)
    sectionRefs.current[k]?.scrollIntoView({ behavior: 'smooth', block: 'start' })
  }

  const saveCompany = async () => {
    const v = await companyForm.validateFields()
    const mobile = [v.phone1, v.phone2, v.phone3].filter(Boolean).join('-')
    const businessNumber = [v.biz1, v.biz2, v.biz3].filter(Boolean).join('-')
    save.mutate({
      company: {
        name: v.name,
        managerName: v.managerName,
        mobile,
        businessName: v.businessName,
        businessNumber,
        ceo: v.ceo,
        bizType: v.bizType,
        bizItem: v.bizItem,
        address: v.address } })
  }

  const saveAccessIps = () => {
    save.mutate({ accessIps: { enabled: ipEnabled, ips: localIps } })
  }

  const saveMasking = async () => {
    const v = await maskForm.validateFields()
    save.mutate({ masking: v })
  }

  const saveCategories = () => {
    save.mutate({ outCategories: categories })
  }

  const saveStock = async () => {
    const v = await stockForm.validateFields()
    save.mutate({ stock: v })
  }

  const saveOpen = async () => {
    const v = await openForm.validateFields()
    save.mutate({ open: v })
  }

  const addIp = () => {
    const ip = ipInput.trim()
    if (!ip) {
      message.warning('아이피를 입력하세요.')
      return
    }
    if (localIps.includes(ip)) {
      message.warning('이미 등록된 아이피입니다.')
      return
    }
    setLocalIps((prev) => [...prev, ip])
    setIpInput('')
  }

  const addCategory = () => {
    const name = categoryInput.trim()
    if (!name) {
      message.warning('분류명을 입력하세요.')
      return
    }
    if (categories.includes(name)) {
      message.warning('이미 등록된 분류입니다.')
      return
    }
    setCategories((prev) => [...prev, name])
    setCategoryInput('')
  }

  return (
    <div className="stock-page pref-page">
      <div className="stock-title">
        <div>
          <h2><SettingOutlined style={{ marginRight: 8 }} />기본설정</h2>
          <p>에이전트 이용에 필요한 기본적인 설정을 하실 수 있습니다.</p>
        </div>
      </div>

      <Card className="stock-table-card pref-card" size="small" loading={query.isLoading}>
        <Tabs
          className="pref-tabs"
          activeKey={tab}
          onChange={onTabChange}
          items={TAB_KEYS.map((t) => ({ key: t.key, label: t.label }))}
        />

        <div
          ref={(el) => { sectionRefs.current.company = el }}
          className="pref-section"
          id="pref-company"
        >
          <SectionHead title="사업자정보" desc="등록된 사업자의 정보를 변경하실 수 있습니다." />
          <Form form={companyForm} className="pref-form" requiredMark={false}>
            <table className="pref-table">
              <tbody>
                <tr>
                  <th>업체명</th>
                  <td colSpan={3}>
                    <Form.Item name="name" rules={[{ required: true, message: '업체명을 입력하세요.' }]} noStyle>
                      <Input className="pref-input-wide" />
                    </Form.Item>
                  </td>
                </tr>
                <tr>
                  <th>빌링에이전트 담당자</th>
                  <td>
                    <Form.Item name="managerName" noStyle>
                      <Input className="pref-input-md" />
                    </Form.Item>
                  </td>
                  <th>휴대폰</th>
                  <td>
                    <Space size={6}>
                      <Form.Item name="phone1" noStyle>
                        <Select
                          className="pref-phone-select"
                          options={['010', '011', '016', '017', '018', '019'].map((v) => ({ value: v, label: v }))}
                        />
                      </Form.Item>
                      <Form.Item name="phone2" noStyle>
                        <Input className="pref-phone-input" maxLength={4} />
                      </Form.Item>
                      <Form.Item name="phone3" noStyle>
                        <Input className="pref-phone-input" maxLength={4} />
                      </Form.Item>
                    </Space>
                  </td>
                </tr>
                <tr>
                  <th>상호</th>
                  <td colSpan={3}>
                    <Form.Item name="businessName" noStyle>
                      <Input className="pref-input-wide" />
                    </Form.Item>
                  </td>
                </tr>
                <tr>
                  <th>사업자등록번호</th>
                  <td>
                    <Space size={6}>
                      <Form.Item name="biz1" noStyle>
                        <Input className="pref-biz-sm" maxLength={3} />
                      </Form.Item>
                      <span>-</span>
                      <Form.Item name="biz2" noStyle>
                        <Input className="pref-biz-xs" maxLength={2} />
                      </Form.Item>
                      <span>-</span>
                      <Form.Item name="biz3" noStyle>
                        <Input className="pref-biz-md" maxLength={5} />
                      </Form.Item>
                    </Space>
                  </td>
                  <th>대표</th>
                  <td>
                    <Form.Item name="ceo" noStyle>
                      <Input className="pref-input-md" />
                    </Form.Item>
                  </td>
                </tr>
                <tr>
                  <th>업태</th>
                  <td>
                    <Form.Item name="bizType" noStyle>
                      <Input className="pref-input-md" />
                    </Form.Item>
                  </td>
                  <th>종목</th>
                  <td>
                    <Form.Item name="bizItem" noStyle>
                      <Input className="pref-input-md" />
                    </Form.Item>
                  </td>
                </tr>
                <tr>
                  <th>주소</th>
                  <td colSpan={3}>
                    <Form.Item name="address" noStyle>
                      <Input className="pref-input-wide" />
                    </Form.Item>
                  </td>
                </tr>
              </tbody>
            </table>
            <div className="pref-actions">
              <Button type="primary" loading={save.isPending} onClick={saveCompany}>적용</Button>
            </div>
          </Form>
        </div>

        <div
          ref={(el) => { sectionRefs.current.accessIp = el }}
          className="pref-section"
          id="pref-accessIp"
        >
          <SectionHead
            title="접속아이피"
            desc="허용된 아이피에서만 접속하도록 제한할 수 있습니다. 미사용 시 모든 아이피에서 접속 가능합니다."
          />
          <div className="pref-block">
            <div className="pref-row">
              <span className="pref-label">접속제한</span>
              <Radio.Group
                value={ipEnabled}
                onChange={(e) => setIpEnabled(e.target.value)}
                options={[
                  { value: true, label: '사용' },
                  { value: false, label: '미사용' },
                ]}
              />
            </div>
            <div className="pref-row">
              <span className="pref-label">아이피 등록</span>
              <Space>
                <Input
                  className="pref-input-md"
                  placeholder="예: 123.456.789.012"
                  value={ipInput}
                  onChange={(e) => setIpInput(e.target.value)}
                  onPressEnter={addIp}
                />
                <Button icon={<PlusOutlined />} onClick={addIp}>추가</Button>
              </Space>
            </div>
            <CareTable
              className="pref-list-table"
              size="small"
              rowKey="ip"
              pagination={false}
              dataSource={localIps.map((ip) => ({ ip }))}
              columns={[
                { title: 'No', width: 60, align: 'center' as const, render: (_: unknown, __: { ip: string }, i: number) => i + 1 },
                { title: '아이피', dataIndex: 'ip' },
                {
                  title: '관리',
                  width: 90,
                  align: 'center' as const,
                  render: (_: unknown, row: { ip: string }) => (
                    <Button
                      size="small"
                      danger
                      onClick={() => setLocalIps((prev) => prev.filter((x) => x !== row.ip))}
                    >
                      삭제
                    </Button>
                  ) },
              ]}
              locale={{ emptyText: '등록된 아이피가 없습니다.' }}
            />
            <div className="pref-actions">
              <Button type="primary" loading={save.isPending} onClick={saveAccessIps}>적용</Button>
            </div>
          </div>
        </div>

        <div
          ref={(el) => { sectionRefs.current.masking = el }}
          className="pref-section"
          id="pref-masking"
        >
          <SectionHead
            title="개인정보마스킹"
            desc="목록/상세 화면에서 개인정보를 마스킹 처리할지 설정합니다."
          />
          <Form form={maskForm} className="pref-block">
            <div className="pref-row">
              <span className="pref-label">마스킹 사용</span>
              <Form.Item name="enabled" noStyle>
                <Radio.Group
                  options={[
                    { value: true, label: '사용' },
                    { value: false, label: '미사용' },
                  ]}
                />
              </Form.Item>
            </div>
            <div className="pref-row">
              <span className="pref-label">마스킹 항목</span>
              <Space wrap>
                <Form.Item name="name" valuePropName="checked" noStyle>
                  <Checkbox>고객명</Checkbox>
                </Form.Item>
                <Form.Item name="phone" valuePropName="checked" noStyle>
                  <Checkbox>연락처</Checkbox>
                </Form.Item>
                <Form.Item name="rrn" valuePropName="checked" noStyle>
                  <Checkbox>주민번호</Checkbox>
                </Form.Item>
                <Form.Item name="address" valuePropName="checked" noStyle>
                  <Checkbox>주소</Checkbox>
                </Form.Item>
              </Space>
            </div>
            <div className="pref-actions">
              <Button type="primary" loading={save.isPending} onClick={saveMasking}>적용</Button>
            </div>
          </Form>
        </div>

        <div
          ref={(el) => { sectionRefs.current.outCategory = el }}
          className="pref-section"
          id="pref-outCategory"
        >
          <SectionHead
            title="출고처분류"
            desc="출고처 분류를 등록·관리합니다. 재고/개통/정산 화면의 출고분류 선택에 사용됩니다."
          />
          <div className="pref-block">
            <div className="pref-row">
              <span className="pref-label">분류 등록</span>
              <Space>
                <Input
                  className="pref-input-md"
                  placeholder="예: 판매점"
                  value={categoryInput}
                  onChange={(e) => setCategoryInput(e.target.value)}
                  onPressEnter={addCategory}
                />
                <Button icon={<PlusOutlined />} onClick={addCategory}>추가</Button>
              </Space>
            </div>
            <CareTable
              className="pref-list-table"
              size="small"
              rowKey="name"
              pagination={false}
              dataSource={categories.map((name) => ({ name }))}
              columns={[
                { title: 'No', width: 60, align: 'center' as const, render: (_: unknown, __: { name: string }, i: number) => i + 1 },
                { title: '분류명', dataIndex: 'name' },
                {
                  title: '관리',
                  width: 90,
                  align: 'center' as const,
                  render: (_: unknown, row: { name: string }) => (
                    <Button
                      size="small"
                      danger
                      onClick={() => setCategories((prev) => prev.filter((x) => x !== row.name))}
                    >
                      삭제
                    </Button>
                  ) },
              ]}
              locale={{ emptyText: '등록된 분류가 없습니다.' }}
            />
            <div className="pref-actions">
              <Button type="primary" loading={save.isPending} onClick={saveCategories}>적용</Button>
            </div>
          </div>
        </div>

        <div
          ref={(el) => { sectionRefs.current.stock = el }}
          className="pref-section"
          id="pref-stock"
        >
          <SectionHead title="재고설정" desc="재고 업무에 적용되는 기본 옵션을 설정합니다." />
          <Form form={stockForm} className="pref-block">
            <div className="pref-row">
              <span className="pref-label">일련번호 중복검사</span>
              <Form.Item name="duplicateSerialCheck" noStyle>
                <Radio.Group
                  options={[
                    { value: true, label: '사용' },
                    { value: false, label: '미사용' },
                  ]}
                />
              </Form.Item>
            </div>
            <div className="pref-row">
              <span className="pref-label">마이너스 재고 허용</span>
              <Form.Item name="allowNegative" noStyle>
                <Radio.Group
                  options={[
                    { value: true, label: '허용' },
                    { value: false, label: '미허용' },
                  ]}
                />
              </Form.Item>
            </div>
            <div className="pref-row">
              <span className="pref-label">자동회수 기준일</span>
              <Space>
                <Form.Item name="autoRecallDays" noStyle>
                  <InputNumber min={0} max={365} className="pref-number" />
                </Form.Item>
                <Typography.Text type="secondary">일 (0이면 미사용)</Typography.Text>
              </Space>
            </div>
            <div className="pref-actions">
              <Button type="primary" loading={save.isPending} onClick={saveStock}>적용</Button>
            </div>
          </Form>
        </div>

        <div
          ref={(el) => { sectionRefs.current.open = el }}
          className="pref-section"
          id="pref-open"
        >
          <SectionHead title="개통설정" desc="개통 업무에 적용되는 기본 옵션을 설정합니다." />
          <Form form={openForm} className="pref-block">
            <div className="pref-row">
              <span className="pref-label">유심 필수</span>
              <Form.Item name="requireUsim" noStyle>
                <Radio.Group
                  options={[
                    { value: true, label: '필수' },
                    { value: false, label: '선택' },
                  ]}
                />
              </Form.Item>
            </div>
            <div className="pref-row">
              <span className="pref-label">단말기 필수</span>
              <Form.Item name="requirePhone" noStyle>
                <Radio.Group
                  options={[
                    { value: true, label: '필수' },
                    { value: false, label: '선택' },
                  ]}
                />
              </Form.Item>
            </div>
            <div className="pref-row">
              <span className="pref-label">기본 개통유형</span>
              <Form.Item name="defaultOpenHow" noStyle>
                <Select
                  allowClear
                  placeholder="선택"
                  className="pref-input-md"
                  options={['신규', '기변', 'MNP', '보상'].map((v) => ({ value: v, label: v }))}
                />
              </Form.Item>
            </div>
            <div className="pref-row">
              <span className="pref-label">개통 시 자동정산반영</span>
              <Form.Item name="autoSettle" noStyle>
                <Radio.Group
                  options={[
                    { value: true, label: '사용' },
                    { value: false, label: '미사용' },
                  ]}
                />
              </Form.Item>
            </div>
            <div className="pref-actions">
              <Button type="primary" loading={save.isPending} onClick={saveOpen}>적용</Button>
            </div>
          </Form>
        </div>
      </Card>
    </div>
  )
}
