import { useEffect, useMemo, useState } from 'react'
import { useMutation, useQuery } from '@tanstack/react-query'
import { useLocation, useNavigate, useSearchParams } from 'react-router-dom'
import dayjs from 'dayjs'
import {
  AutoComplete, Button, Card, Checkbox, Col, DatePicker, Form, Input, InputNumber, Radio, Row, Select, Space, message } from 'antd'
import { openApi } from '../../api/opens'
import { resourceApi } from '../../api/resources'
import { stockApi } from '../../api/stocks'

const options = (values: string[]) => values.map((value) => ({ value, label: value }))
const hours = Array.from({ length: 24 }, (_, i) => ({ value: i, label: `${String(i).padStart(2, '0')}시` }))
const minutes = [0, 10, 20, 30, 40, 50].map((v) => ({ value: v, label: `${String(v).padStart(2, '0')}분` }))

type OpenType = '할부' | '현금' | '유심'
const typeFromPath = (path?: string): OpenType => {
  if (path?.includes('write2')) return '현금'
  if (path?.includes('write3')) return '유심'
  return '할부'
}
const pathForType = (type: OpenType) => ({
  할부: '/care/open/open-form-write1',
  현금: '/care/open/open-form-write2',
  유심: '/care/open/open-form-write3' }[type])

function MoneyField({ name, label, tip }: { name: string; label: string; tip?: string }) {
  return (
    <Form.Item name={name} label={label} tooltip={tip}>
      <InputNumber className="open-money" controls={false} addonAfter="원" />
    </Form.Item>
  )
}

export default function OpenWritePage() {
  const navigate = useNavigate()
  const location = useLocation()
  const [search] = useSearchParams()
  const editId = search.get('id') ? Number(search.get('id')) : null
  const [form] = Form.useForm()
  const [openType, setOpenType] = useState<OpenType>(typeFromPath(location.pathname))
  const [phoneInfo, setPhoneInfo] = useState<Record<string, unknown> | null>(null)
  const [usimInfo, setUsimInfo] = useState<Record<string, unknown> | null>(null)
  const [phoneOptions, setPhoneOptions] = useState<{ value: string; label: string; stock: Record<string, unknown> }[]>([])
  const [usimOptions, setUsimOptions] = useState<{ value: string; label: string; stock: Record<string, unknown> }[]>([])
  const [keepDays, setKeepDays] = useState<number | null>(null)
  const [keepBase, setKeepBase] = useState(dayjs())

  const companies = useQuery({ queryKey: ['open-write-companies'], queryFn: () => resourceApi.list('companies', { size: 200 }) })
  const detail = useQuery({
    queryKey: ['open-detail', editId],
    queryFn: () => openApi.get(editId!),
    enabled: Boolean(editId) })

  const outOptions = useMemo(
    () => (companies.data?.items ?? []).filter((c) => ['SHOP', 'DEALER', 'OUT'].includes(String(c.type))).map((c) => ({ value: c.id, label: String(c.name) })),
    [companies.data],
  )

  useEffect(() => {
    const next = typeFromPath(location.pathname)
    setOpenType(next)
    form.setFieldValue('gubun', next)
  }, [location.pathname, form])

  useEffect(() => {
    if (!detail.data) return
    const row = detail.data
    setOpenType((row.gubun as OpenType) || '할부')
    const phone = String(row.openphone ?? '').replace(/\D/g, '')
    form.setFieldsValue({
      ...row,
      opendate: row.opendate ? dayjs(String(row.opendate)) : dayjs(),
      phone1: phone.slice(0, 3) || '010',
      phone2: phone.slice(3, 7),
      phone3: phone.slice(7, 11),
      feeDiscount: false })
    if (row.pserial) setPhoneInfo({ model: row.pmodel, color: row.pcolor, serial: row.pserial, incompanyName: row.incompanyName, outcompanyName: row.outcompanyName, inprice: row.inprice })
    if (row.userial) setUsimInfo({ model: row.umodel, serial: row.userial })
  }, [detail.data])

  const save = useMutation({
    mutationFn: async (values: Record<string, unknown>) => {
      const openphone = `${values.phone1}-${values.phone2}-${values.phone3}`
      const payload: Record<string, unknown> = {
        ...values,
        gubun: openType,
        salehow: openType,
        openphone,
        opendate: values.opendate ? dayjs(values.opendate as dayjs.Dayjs).format('YYYY-MM-DD') : dayjs().format('YYYY-MM-DD'),
        pserial: openType === '유심' ? null : (phoneInfo?.serial ?? values.pserial),
        pmodel: openType === '유심' ? null : (phoneInfo?.model ?? values.pmodel),
        pcolor: openType === '유심' ? null : (phoneInfo?.color ?? values.pcolor),
        phoneStockId: openType === '유심' ? null : phoneInfo?.id,
        userial: usimInfo?.serial ?? values.userial,
        umodel: usimInfo?.model ?? values.umodel,
        usimStockId: usimInfo?.id,
        incompanyId: phoneInfo?.incompanyId ?? values.incompanyId,
        inprice: values.inprice ?? phoneInfo?.inprice,
        openStatus: values.openStatus ?? '정상',
        state: 'OPEN' }
      delete payload.phone1
      delete payload.phone2
      delete payload.phone3
      delete payload.feeDiscount
      delete payload.dates
      if (editId) return openApi.save(editId, payload)
      return openApi.create(payload)
    },
    onSuccess: () => { message.success(editId ? '개통 정보를 수정했습니다.' : '개통 등록이 완료되었습니다.'); navigate('/care/open/open') },
    onError: (e: Error) => message.error(e.message || '저장에 실패했습니다.') })

  const lookupSerial = async (serial: string, kind: 'phone' | 'usim') => {
    if (!serial || serial.length < 3) return
    const list = await openApi.serialLookup(serial, kind === 'usim' ? '유심' : '휴대폰')
    const mapped = list.map((stock) => ({
      value: String(stock.serial),
      label: `${stock.serial} / ${stock.model ?? '-'} / ${stock.statusLabel ?? stock.state}`,
      stock }))
    if (kind === 'phone') setPhoneOptions(mapped)
    else setUsimOptions(mapped)
  }

  const applyPhone = (stock: Record<string, unknown>) => {
    setPhoneInfo(stock)
    form.setFieldsValue({
      pserial: stock.serial,
      pmodel: stock.model,
      pcolor: stock.color,
      phoneStockId: stock.id,
      telecom: stock.telecom ?? form.getFieldValue('telecom'),
      incompanyId: stock.incompanyId,
      inprice: stock.inprice })
  }
  const applyUsim = (stock: Record<string, unknown>) => {
    setUsimInfo(stock)
    form.setFieldsValue({ userial: stock.serial, umodel: stock.model, usimStockId: stock.id })
  }

  const changeType = (type: OpenType) => {
    setOpenType(type)
    form.setFieldValue('gubun', type)
    navigate(`${pathForType(type)}${editId ? `?id=${editId}` : ''}`, { replace: true })
    if (type === '유심') { setPhoneInfo(null); form.setFieldsValue({ pserial: undefined, pmodel: undefined, phoneStockId: undefined }) }
  }

  const keepResult = keepDays == null ? '' : keepBase.add(keepDays, 'day').format('YYYY-MM-DD')

  const quickIn = async (gubun: string) => {
    const serial = window.prompt(`${gubun} 일련번호를 입력하세요`)
    if (!serial) return
    try {
      await stockApi.create({ gubun, telecom: form.getFieldValue('telecom') || 'SKT', serial, model: gubun === '유심' ? 'USIM' : '미지정', cond: '정상', state: 'IN', indate: dayjs().format('YYYY-MM-DD'), processDate: dayjs().format('YYYY-MM-DD') })
      message.success('간편입고 되었습니다.')
      await lookupSerial(serial, gubun === '유심' ? 'usim' : 'phone')
    } catch (e) { message.error((e as Error).message) }
  }

  return (
    <div className="open-write-page">
      <div className="stock-title">
        <div>
          <h2>개통 등록</h2>
          <p>아래 양식에 개통 정보를 순서대로 입력해 주세요. ('필수' 표시는 필수항목입니다.)</p>
        </div>
        <div className="open-type-toggle">
          {(['할부', '현금', '유심'] as OpenType[]).map((type) => (
            <label key={type} className={openType === type ? 'active' : ''}>
              <input type="checkbox" checked={openType === type} onChange={() => changeType(type)} />
              {type}개통
            </label>
          ))}
        </div>
      </div>

      <Form
        form={form}
        layout="horizontal"
        labelCol={{ flex: '110px' }}
        wrapperCol={{ flex: 1 }}
        initialValues={{
          gubun: openType,
          telecom: 'SKT',
          openhow: '신규',
          openStatus: '정상',
          supportType: '선택약정',
          opendate: dayjs(),
          openHour: dayjs().hour(),
          openMinute: 0,
          phone1: '010',
          salemon: openType === '할부' ? 24 : 0,
          agreemon: 24,
          salehow: openType,
          joinhow: '일반',
          usimhow: '신규유심' }}
        onFinish={(values) => save.mutate(values)}
      >
        <Row gutter={16}>
          <Col xs={24} xl={18}>
            <Card className="open-section" size="small" title={null}>
              <Row gutter={16}>
                <Col xs={24} md={12}>
                  <div className="open-block-head">
                    <strong>단말기</strong>
                    {openType !== '유심' && <Button size="small" onClick={() => quickIn('휴대폰')}>간편입고</Button>}
                  </div>
                  {openType === '유심' ? (
                    <div className="open-na">관계없음</div>
                  ) : (
                    <>
                      <Form.Item label="일련번호" required>
                        <AutoComplete
                          options={phoneOptions}
                          onSearch={(v) => lookupSerial(v, 'phone')}
                          onSelect={(_, opt) => applyPhone((opt as { stock: Record<string, unknown> }).stock)}
                          placeholder="단말기 일련번호를 입력해주세요"
                        >
                          <Input onBlur={(e) => { const v = e.target.value; if (v.length >= 3) lookupSerial(v, 'phone').then(() => { const hit = phoneOptions.find((o) => o.value === v); if (hit) applyPhone(hit.stock) }) }} />
                        </AutoComplete>
                      </Form.Item>
                      <p className="open-hint">(3자리 이상 입력 시 검색됩니다)</p>
                      <div className="open-info-lines">
                        <div><span>단말기정보</span><b>{phoneInfo ? `${phoneInfo.model ?? '-'} / ${phoneInfo.color ?? '-'}` : '-'}</b></div>
                        <div><span>입고정보</span><b>{phoneInfo ? `${phoneInfo.incompanyName ?? '-'} / ${phoneInfo.inprice != null ? Number(phoneInfo.inprice).toLocaleString() + '원' : '-'}` : '-'}</b></div>
                        <div><span>출고정보</span><b>{phoneInfo ? `${phoneInfo.outcompanyName ?? '-'} / ${phoneInfo.statusLabel ?? phoneInfo.state ?? '-'}` : '-'}</b></div>
                      </div>
                    </>
                  )}
                </Col>
                <Col xs={24} md={12}>
                  <div className="open-block-head">
                    <strong>유심</strong>
                    <Button size="small" onClick={() => quickIn('유심')}>간편입고</Button>
                  </div>
                  <Form.Item label="일련번호">
                    <AutoComplete
                      options={usimOptions}
                      onSearch={(v) => lookupSerial(v, 'usim')}
                      onSelect={(_, opt) => applyUsim((opt as { stock: Record<string, unknown> }).stock)}
                      placeholder="유심 일련번호를 입력해주세요"
                    >
                      <Input />
                    </AutoComplete>
                  </Form.Item>
                  <p className="open-hint">(3자리 이상 입력 시 검색됩니다)</p>
                  <div className="open-info-lines">
                    <div><span>유심정보</span><b>{usimInfo ? String(usimInfo.model ?? usimInfo.serial ?? '-') : '-'}</b></div>
                    <div><span>입고정보</span><b>{usimInfo ? `${usimInfo.incompanyName ?? '-'} / ${usimInfo.inprice != null ? Number(usimInfo.inprice).toLocaleString() + '원' : '-'}` : '-'}</b></div>
                    <div><span>출고정보</span><b>{usimInfo ? `${usimInfo.outcompanyName ?? '-'} / ${usimInfo.statusLabel ?? usimInfo.state ?? '-'}` : '-'}</b></div>
                  </div>
                </Col>
              </Row>
            </Card>

            <Card className="open-section" size="small" title="정책정보">
              {openType === '유심' && (
                <Form.Item name="supportType" label="지원유형">
                  <Radio.Group options={[{ value: '일반', label: '일반' }, { value: '선택약정', label: '선택약정' }]} />
                </Form.Item>
              )}
              <Row gutter={24}>
                <Col xs={24} md={12}>
                  {openType !== '유심' && (
                    <>
                      <MoneyField name="inprice" label="입고가" />
                      <Form.Item label="공통지원금">
                        <Space>
                          <Form.Item name="commonSupport" noStyle><InputNumber className="open-money" controls={false} addonAfter="원" /></Form.Item>
                          <Form.Item name="feeDiscount" valuePropName="checked" noStyle><Checkbox>요금할인</Checkbox></Form.Item>
                        </Space>
                      </Form.Item>
                      {openType === '할부' && <MoneyField name="extraSupport" label="추가지원금" tip="추가 지원금" />}
                      <MoneyField name={openType === '할부' ? 'switchSupport' : 'moveprice'} label="전환지원금" />
                      <Form.Item label="포인트/카드수납">
                        <Space>
                          <Form.Item name="pointPay" noStyle><InputNumber className="open-money" controls={false} addonAfter="원" /></Form.Item>
                          <Button size="small">+ 추가</Button>
                        </Space>
                      </Form.Item>
                      <MoneyField name="preprice" label="선납금" tip="선납금" />
                      {openType === '할부' && <MoneyField name="joinprice" label="할부원금" />}
                      {openType === '현금' && <MoneyField name="extraSupport" label="추가지원금" />}
                      {openType === '현금' && <MoneyField name="joinprice" label="할부원금" />}
                      <MoneyField name="netprice" label="NET가" tip="최종 NET가" />
                    </>
                  )}
                  {openType === '유심' && (
                    <>
                      <MoneyField name="basicprice1" label="기본정책" />
                      <MoneyField name="basicprice3" label="추가정책" />
                      <MoneyField name="etcprice1" label="기타정책1" />
                      <MoneyField name="netprice" label="NET가" tip="최종 NET가" />
                    </>
                  )}
                </Col>
                <Col xs={24} md={12}>
                  <Form.Item name="basicprice4" label="정책번호"><InputNumber className="open-money" controls={false} addonAfter="호" /></Form.Item>
                  {openType !== '유심' && (
                    <>
                      <MoneyField name="basicprice1" label="기본정책" />
                      <MoneyField name="basicprice2" label="구두정책" />
                      <MoneyField name="basicprice3" label="추가정책" />
                      <MoneyField name="gradePrice" label="그레이드" />
                      <MoneyField name="etcprice1" label="기타정책1" />
                      <MoneyField name="etcprice2" label="기타정책2" />
                    </>
                  )}
                  {openType === '유심' && (
                    <>
                      <MoneyField name="basicprice2" label="구두정책" />
                      <MoneyField name="gradePrice" label="그레이드" />
                      <MoneyField name="etcprice2" label="기타정책2" />
                    </>
                  )}
                </Col>
              </Row>
            </Card>

            <Card className="open-section" size="small" title="가입정보">
              <Row gutter={24}>
                <Col xs={24} md={12}>
                  <Form.Item name="outcompanyId" label="출고처" rules={[{ required: true, message: '출고처를 선택하세요' }]}>
                    <Select showSearch optionFilterProp="label" options={outOptions} placeholder="출고처 선택" />
                  </Form.Item>
                  <Form.Item name="name" label="고객명" rules={[{ required: true, message: '고객명을 입력하세요' }]}>
                    <Input placeholder="고객명" />
                  </Form.Item>
                  <Form.Item label="개통일자" required>
                    <Space wrap>
                      <Form.Item name="opendate" noStyle rules={[{ required: true }]}><DatePicker /></Form.Item>
                      <Form.Item name="openHour" noStyle><Select className="w-100" options={hours} /></Form.Item>
                      <Form.Item name="openMinute" noStyle><Select className="w-100" options={minutes} /></Form.Item>
                    </Space>
                  </Form.Item>
                  <Form.Item label="개통번호" required>
                    <Space.Compact>
                      <Form.Item name="phone1" noStyle rules={[{ required: true }]}><Select className="w-100" options={options(['010', '011', '016', '017', '018', '019'])} /></Form.Item>
                      <Form.Item name="phone2" noStyle rules={[{ required: true }]}><Input className="w-100" maxLength={4} /></Form.Item>
                      <Form.Item name="phone3" noStyle rules={[{ required: true }]}><Input className="w-100" maxLength={4} /></Form.Item>
                    </Space.Compact>
                  </Form.Item>
                  <Form.Item name="telecom" label="통신사" rules={[{ required: true }]}>
                    <Select options={options(['SKT', 'KT', 'LGU+'])} />
                  </Form.Item>
                  <Form.Item name="openhow" label="종류" rules={[{ required: true }]}>
                    <Select options={options(['신규', '번호이동', '보상', '기변', '메이징', '가개통', '선불개통'])} />
                  </Form.Item>
                </Col>
                <Col xs={24} md={12}>
                  <Form.Item name="plan" label="요금제" rules={[{ required: true, message: '요금제를 입력하세요' }]}>
                    <Input placeholder="요금제명" />
                  </Form.Item>
                  <Form.Item name="planprice" label="요금제금액"><InputNumber className="open-money" controls={false} addonAfter="원" /></Form.Item>
                  <Form.Item name="salemon" label="할부개월"><InputNumber className="open-money" min={0} addonAfter="개월" /></Form.Item>
                  <Form.Item name="agreemon" label="약정개월"><InputNumber className="open-money" min={0} addonAfter="개월" /></Form.Item>
                  <Form.Item name="joinhow" label="가입유형"><Select options={options(['일반', '선택약정', '공시지원'])} /></Form.Item>
                  <Form.Item name="usimhow" label="유심방식"><Select options={options(['신규유심', '기존유심', 'eSIM'])} /></Form.Item>
                  <Form.Item name="salesperson" label="영업사원"><Select allowClear options={options(['김영업', '이영업'])} /></Form.Item>
                  <Form.Item name="employee" label="직원"><Select allowClear options={options(['demo'])} /></Form.Item>
                  <Form.Item name="outCategory" label="출고분류"><Select allowClear options={options(['판매점', '도매'])} /></Form.Item>
                  <Form.Item name="openStatus" label="상태"><Select options={options(['정상', '보류', '취소'])} /></Form.Item>
                </Col>
              </Row>
            </Card>

            <Card className="open-section" size="small" title="정산/마진">
              <Row gutter={24}>
                <Col xs={24} md={12}>
                  <MoneyField name="sellprice" label="정산금" />
                  <MoneyField name="declprice1" label="차감" />
                  <MoneyField name="dealermargin1" label="마진" />
                  <MoneyField name="usimprice" label="유심비" />
                </Col>
                <Col xs={24} md={12}>
                  <MoneyField name="memberpoint" label="멤버십포인트" />
                  <Form.Item name="decltype" label="할인유형"><Select allowClear options={options(['단말할인', '요금할인', '기타'])} /></Form.Item>
                  <Form.Item name="dealermemo" label="딜러메모"><Input /></Form.Item>
                </Col>
              </Row>
            </Card>

            <Card className="open-section" size="small" title="메모">
              <Form.Item name="memo1" label="메모1"><Input.TextArea rows={2} /></Form.Item>
              <Form.Item name="memo2" label="메모2"><Input.TextArea rows={2} /></Form.Item>
              <Form.Item name="memo3" label="메모3"><Input.TextArea rows={2} /></Form.Item>
            </Card>

            <div className="open-actions">
              <Button onClick={() => navigate('/care/open/open')}>목록</Button>
              <Button type="primary" htmlType="submit" loading={save.isPending}>{editId ? '수정' : '등록'}</Button>
            </div>
          </Col>

          <Col xs={24} xl={6}>
            <Card className="keep-calc" size="small" title="유지일 계산">
              <DatePicker value={keepBase} onChange={(v) => v && setKeepBase(v)} style={{ width: '100%', marginBottom: 8 }} />
              <div className="keep-row">
                <span>+</span>
                <InputNumber min={0} value={keepDays ?? undefined} onChange={(v) => setKeepDays(v)} style={{ width: 70 }} />
                <span>일 =</span>
                <Input value={keepResult} readOnly />
              </div>
            </Card>
          </Col>
        </Row>
      </Form>
    </div>
  )
}
