import { useEffect, useMemo, useState } from 'react'
import { useNavigate, useSearchParams } from 'react-router-dom'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import dayjs from 'dayjs'
import {
  Button, Card, Checkbox, Col, DatePicker, Form, Input, InputNumber, Radio, Row, Select, Space, message } from 'antd'
import CareTable from '../../components/CareTable'
import { EditOutlined, PlusOutlined, SettingOutlined, UnorderedListOutlined } from '@ant-design/icons'
import Modal from '../../components/DraggableModal'
import client, { apiPrefix, unwrap, type ApiResponse } from '../../api/client'
import { money, options, type PageResult, type Row as DataRow } from './homesShared'

type ProductLine = {
  key: string
  productId?: number
  name: string
  months?: number
  policyAmount?: number
}

function splitPhone(phone?: string) {
  const d = String(phone ?? '').replace(/\D/g, '')
  return {
    phone1: d.slice(0, 3) || '010',
    phone2: d.slice(3, 7),
    phone3: d.slice(7, 11) }
}

function joinPhone(v: Record<string, unknown>, prefix = 'phone') {
  const a = String(v[`${prefix}1`] ?? '').trim()
  const b = String(v[`${prefix}2`] ?? '').trim()
  const c = String(v[`${prefix}3`] ?? '').trim()
  if (!a && !b && !c) return ''
  return `${a}-${b}-${c}`
}

export default function ContractWritePage() {
  const [params] = useSearchParams()
  const type = params.get('type') === 'home' ? 'HOME' : 'INTERNET'
  const id = params.get('id')
  const navigate = useNavigate()
  const qc = useQueryClient()
  const [form] = Form.useForm()
  const [productForm] = Form.useForm()
  const [lines, setLines] = useState<ProductLine[]>([])
  const [productOpen, setProductOpen] = useState(false)
  const back = type === 'HOME' ? '/care/contract/home' : '/care/contract/internet'
  const title = type === 'HOME' ? '홈렌탈 접수등록' : '인터넷 접수등록'
  const guide = type === 'HOME'
    ? '홈렌탈상품의 계약정보를 아래의 양식 순서대로 입력해주세요. (필수 표시는 필수항목입니다.)'
    : '인터넷상품의 계약정보를 아래의 양식 순서대로 입력해주세요. (필수 표시는 필수항목입니다.)'
  const sameContact = Form.useWatch('sameContact', form)

  const detail = useQuery({
    queryKey: ['homes-contract', id],
    enabled: !!id,
    queryFn: async () => {
      const { data } = await client.get<ApiResponse<Record<string, unknown>>>(`${apiPrefix()}/homes/contracts/${id}`)
      return unwrap(data)
    } })

  const agencies = useQuery({
    queryKey: ['homes/agencies-options'],
    queryFn: async () => {
      const { data } = await client.get<ApiResponse<PageResult>>(`${apiPrefix()}/homes/agencies`, { params: { page: 0, size: 200 } })
      return unwrap(data)
    } })

  const products = useQuery({
    queryKey: ['homes/products-for-contract', type],
    queryFn: async () => {
      const { data } = await client.get<ApiResponse<PageResult>>(`${apiPrefix()}/homes/products`, {
        params: { kind: type, category: 'ALL', page: 0, size: 200 } })
      return unwrap(data)
    } })

  useEffect(() => {
    if (!detail.data) return
    const d = detail.data
    const phone = splitPhone(String(d.phone ?? ''))
    const installPhone = splitPhone(String(d.installPhone ?? d.phone ?? ''))
    const birth = String(d.birthDate ?? '').split('-')
    form.setFieldsValue({
      ...d,
      ...phone,
      installPhone1: installPhone.phone1,
      installPhone2: installPhone.phone2,
      installPhone3: installPhone.phone3,
      birthYear: birth[0] || undefined,
      birthMonth: birth[1] || undefined,
      birthDay: birth[2] || undefined,
      contractDate: d.contractDate ? dayjs(String(d.contractDate)) : dayjs(),
      installDate: d.installDate ? dayjs(String(d.installDate)) : undefined,
      customerGrade: d.customerGrade || '분류없음',
      sameContact: d.sameContact ?? false })
    const names = String(d.products ?? '').split(',').map((v) => v.trim()).filter(Boolean)
    setLines(names.map((name, i) => ({
      key: `e-${i}`,
      name,
      months: Number(d.months || 0) || undefined,
      policyAmount: names.length ? Number(d.policySum || 0) / names.length : undefined })))
  }, [detail.data, form])

  useEffect(() => {
    if (!sameContact) return
    const values = form.getFieldsValue()
    form.setFieldsValue({
      installPhone1: values.phone1,
      installPhone2: values.phone2,
      installPhone3: values.phone3,
      installZip: values.zipcode,
      installAddress: values.address,
      installAddressDetail: values.addressDetail })
  }, [sameContact, form])

  const policySum = useMemo(
    () => lines.reduce((s, l) => s + Number(l.policyAmount || 0), 0),
    [lines],
  )

  const save = useMutation({
    mutationFn: async (values: Record<string, unknown>) => {
      if (!lines.length) throw new Error('계약 상품을 추가하세요.')
      const birthParts = [values.birthYear, values.birthMonth, values.birthDay].filter(Boolean)
      const payload: Record<string, unknown> = {
        ...values,
        kind: type,
        status: values.status || (id ? detail.data?.status : '접수') || '접수',
        phone: joinPhone(values, 'phone'),
        installPhone: joinPhone(values, 'installPhone'),
        birthDate: birthParts.length === 3
          ? `${values.birthYear}-${String(values.birthMonth).padStart(2, '0')}-${String(values.birthDay).padStart(2, '0')}`
          : null,
        contractDate: values.contractDate ? dayjs(values.contractDate as string).format('YYYY-MM-DD') : null,
        installDate: values.installDate ? dayjs(values.installDate as string).format('YYYY-MM-DD') : null,
        products: lines.map((l) => l.name).join(', '),
        months: lines[0]?.months ?? null,
        policySum,
        settleAmount: values.settleAmount ?? policySum,
        margin: values.margin ?? 0 }
      ;['phone1', 'phone2', 'phone3', 'installPhone1', 'installPhone2', 'installPhone3', 'birthYear', 'birthMonth', 'birthDay'].forEach((k) => {
        delete payload[k]
      })
      if (id) {
        const { data } = await client.put(`${apiPrefix()}/homes/contracts/${id}`, payload)
        return unwrap(data)
      }
      const { data } = await client.post(`${apiPrefix()}/homes/contracts`, payload)
      return unwrap(data)
    },
    onSuccess: () => {
      message.success(id ? '수정했습니다.' : '등록했습니다.')
      qc.invalidateQueries({ queryKey: ['homes/contracts'] })
      navigate(back)
    },
    onError: (e: Error) => message.error(e.message) })

  const agencyOptions = useMemo(
    () => (agencies.data?.list || []).map((a) => ({ value: String(a.name), label: String(a.name) })),
    [agencies.data],
  )

  const productOptions = useMemo(
    () => (products.data?.list || []).map((p: DataRow) => ({
      value: p.id,
      label: `${p.company ? `[${p.company}] ` : ''}${p.name}`,
      raw: p })),
    [products.data],
  )

  const addProduct = (values: { productId: number }) => {
    const found = productOptions.find((o) => o.value === values.productId)
    if (!found) return
    const p = found.raw
    setLines((prev) => [
      ...prev,
      {
        key: `p-${p.id}-${Date.now()}`,
        productId: Number(p.id),
        name: String(p.name),
        months: Number(p.months || 0) || undefined,
        policyAmount: Number(p.policyAmount || 0) },
    ])
    setProductOpen(false)
    productForm.resetFields()
  }

  const searchAddress = (target: 'customer' | 'install') => {
    message.info('주소검색(데모) — 직접 입력해 주세요.')
    if (target === 'customer') {
      form.setFieldsValue({ zipcode: form.getFieldValue('zipcode') || '06236', address: form.getFieldValue('address') || '서울특별시 강남구' })
    } else {
      form.setFieldsValue({ installZip: form.getFieldValue('installZip') || '06236', installAddress: form.getFieldValue('installAddress') || '서울특별시 강남구' })
    }
  }

  return (
    <div className="stock-page contract-write-page">
      <div className="contract-write-head">
        <div className="stock-title contract-write-title">
          <h2>
            <EditOutlined className="product-title-icon" />
            {title}
          </h2>
          <div className="contract-write-title-sub">
            <p>{guide}</p>
            <Button icon={<UnorderedListOutlined />} onClick={() => navigate(back)}>
              목록
            </Button>
          </div>
        </div>
        <div className="contract-write-head-spacer" aria-hidden />
      </div>

      <div className="contract-write-layout">
        <Form
          form={form}
          layout="horizontal"
          labelCol={{ flex: '110px' }}
          wrapperCol={{ flex: 1 }}
          colon={false}
          className="contract-write-form"
          initialValues={{
            customerType: '개인',
            employee: '홍길동',
            customerGrade: '분류없음',
            phone1: '010',
            installPhone1: '010',
            payMethod: '자동이체',
            contractDate: dayjs(),
            sameContact: false,
            settleAmount: 0,
            margin: 0,
            nationality: '내국인' }}
          onFinish={(v) => save.mutate(v)}
        >
          <Card className="open-section" size="small" title="가입정보">
            <Form.Item name="customerType" label="고객구분" rules={[{ required: true }]}>
              <Radio.Group options={[{ value: '개인', label: '개인' }, { value: '사업자', label: '사업자' }]} />
            </Form.Item>
            <Form.Item name="employee" label="접수직원">
              <Select options={options(['홍길동', '홍총괄', '김대표', 'demo'])} />
            </Form.Item>
            <Form.Item label="고객명" required>
              <Space.Compact className="full-width">
                <Form.Item name="customerName" noStyle rules={[{ required: true, message: '고객명을 입력하세요' }]}>
                  <Input style={{ width: '50%' }} />
                </Form.Item>
                <Form.Item name="customerGrade" noStyle>
                  <Select style={{ width: '35%' }} options={options(['분류없음', '단골', '단골1', '단골2', '일반'])} />
                </Form.Item>
                <Button icon={<SettingOutlined />} onClick={() => message.info('고객분류 설정(데모)')} />
              </Space.Compact>
            </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, message: '연락처 필수' }]}>
                  <Input className="w-100" maxLength={4} />
                </Form.Item>
                <Form.Item name="phone3" noStyle rules={[{ required: true, message: '연락처 필수' }]}>
                  <Input className="w-100" maxLength={4} />
                </Form.Item>
              </Space.Compact>
            </Form.Item>
            <Form.Item label="법정생일">
              <Space.Compact>
                <Form.Item name="birthYear" noStyle><Input className="w-100" placeholder="년" maxLength={4} /></Form.Item>
                <Form.Item name="birthMonth" noStyle><Input className="w-100" placeholder="월" maxLength={2} /></Form.Item>
                <Form.Item name="birthDay" noStyle><Input className="w-100" placeholder="일" maxLength={2} /></Form.Item>
              </Space.Compact>
            </Form.Item>
            <Form.Item label="성별/국적">
              <Space>
                <Form.Item name="gender" noStyle>
                  <Select allowClear placeholder="- 성별 -" className="w-130" options={options(['남', '여'])} />
                </Form.Item>
                <Form.Item name="nationality" noStyle>
                  <Select allowClear placeholder="- 국적 -" className="w-130" options={options(['내국인', '외국인'])} />
                </Form.Item>
              </Space>
            </Form.Item>
            <Form.Item name="email" label="이메일"><Input /></Form.Item>
            <Form.Item label="고객주소">
              <Space direction="vertical" className="full-width" size={8}>
                <Space.Compact className="full-width">
                  <Button onClick={() => searchAddress('customer')}>주소검색</Button>
                  <Form.Item name="zipcode" noStyle><Input style={{ width: 100 }} placeholder="우편번호" /></Form.Item>
                  <Form.Item name="address" noStyle><Input placeholder="주소" /></Form.Item>
                </Space.Compact>
                <Form.Item name="addressDetail" noStyle><Input placeholder="상세주소" /></Form.Item>
              </Space>
            </Form.Item>
            <Form.Item name="sameContact" valuePropName="checked" label=" ">
              <Checkbox>상기 고객연락처와 주소가 동일합니다.</Checkbox>
            </Form.Item>
            <Form.Item label="설치연락처">
              <Space.Compact>
                <Form.Item name="installPhone1" noStyle>
                  <Select className="w-100" options={options(['010', '011', '016', '017', '018', '019'])} />
                </Form.Item>
                <Form.Item name="installPhone2" noStyle><Input className="w-100" maxLength={4} /></Form.Item>
                <Form.Item name="installPhone3" noStyle><Input className="w-100" maxLength={4} /></Form.Item>
              </Space.Compact>
            </Form.Item>
            <Form.Item label="설치주소">
              <Space direction="vertical" className="full-width" size={8}>
                <Space.Compact className="full-width">
                  <Button onClick={() => searchAddress('install')}>주소검색</Button>
                  <Form.Item name="installZip" noStyle><Input style={{ width: 100 }} placeholder="우편번호" /></Form.Item>
                  <Form.Item name="installAddress" noStyle><Input placeholder="주소" /></Form.Item>
                </Space.Compact>
                <Form.Item name="installAddressDetail" noStyle><Input placeholder="상세주소" /></Form.Item>
              </Space>
            </Form.Item>
          </Card>

          <Card className="open-section" size="small" title="계약정보">
            <Row gutter={16}>
              <Col xs={24} md={12}>
                <Form.Item name="contractDate" label="계약일" rules={[{ required: true, message: '계약일을 선택하세요' }]}>
                  <DatePicker className="full-width" />
                </Form.Item>
              </Col>
              <Col xs={24} md={12}>
                <Form.Item name="installDate" label="설치완료일">
                  <DatePicker className="full-width" />
                </Form.Item>
              </Col>
              <Col xs={24} md={12}>
                <Form.Item name="agency" label="거래처">
                  <Select allowClear placeholder="- 선택 -" options={agencyOptions.length ? agencyOptions : options(
                    type === 'HOME'
                      ? ['(주)코웨이', '청호나이스', 'SK매직', 'LG전자', '늘푸른통신']
                      : ['늘푸른통신', '대박통신', '스마트홈', 'SK브로드밴드', '(주)코웨이'],
                  )} />
                </Form.Item>
              </Col>
              <Col xs={24} md={12}>
                <Form.Item name="payMethod" label="결제방법">
                  <Radio.Group options={[
                    { value: '자동이체', label: '자동이체' },
                    { value: '카드', label: '카드' },
                    { value: '현금', label: '현금' },
                  ]} />
                </Form.Item>
              </Col>
              <Col xs={24} md={12}>
                <Form.Item name="feeReduction" label="요금감면">
                  <Select allowClear placeholder="- 선택 -" options={options(['해당없음', '기초생활수급자', '장애인', '국가유공자', '차상위계층'])} />
                </Form.Item>
              </Col>
              <Col xs={24} md={12}>
                <Form.Item name="invoiceType" label="청구서">
                  <Select allowClear placeholder="- 선택 -" options={options(['이메일', '문자', '우편', '앱'])} />
                </Form.Item>
              </Col>
            </Row>
          </Card>

          <Card
            className="open-section"
            size="small"
            title="상품정보"
            extra={<Button type="primary" size="small" icon={<PlusOutlined />} onClick={() => setProductOpen(true)}>상품추가</Button>}
          >
            {lines.length === 0 ? (
              <p className="contract-product-empty">아래 상품추가 버튼을 클릭하여 계약 상품을 추가하세요.</p>
            ) : (
              <CareTable
                rowKey="key"
                size="small"
                pagination={false}
                dataSource={lines}
                columns={[
                  { title: '상품명', dataIndex: 'name' },
                  {
                    title: '약정',
                    dataIndex: 'months',
                    width: 100,
                    render: (v: number) => (v ? `${v}개월` : '-') },
                  {
                    title: '정책금액',
                    dataIndex: 'policyAmount',
                    width: 120,
                    align: 'right' as const,
                    render: money },
                  {
                    title: '관리',
                    width: 70,
                    align: 'center' as const,
                    render: (_: unknown, row: ProductLine) => (
                      <Button type="link" danger size="small" onClick={() => setLines((prev) => prev.filter((l) => l.key !== row.key))}>
                        삭제
                      </Button>
                    ) },
                ]}
              />
            )}
            <div className="contract-product-sum">
              <span>정책합산</span>
              <b>{policySum.toLocaleString()}원</b>
            </div>
            <Row gutter={16} style={{ marginTop: 12 }}>
              <Col xs={24} md={12}>
                <Form.Item name="settleAmount" label="정산금액">
                  <InputNumber className="full-width" controls={false} addonAfter="원" />
                </Form.Item>
              </Col>
              <Col xs={24} md={12}>
                <Form.Item name="margin" label="판매마진">
                  <InputNumber className="full-width" controls={false} addonAfter="원" />
                </Form.Item>
              </Col>
              <Col span={24}>
                <Form.Item name="memo" label="비고">
                  <Input.TextArea rows={2} />
                </Form.Item>
              </Col>
            </Row>
          </Card>

          <div className="open-actions">
            <Button onClick={() => navigate(back)}>목록</Button>
            <Button type="primary" htmlType="submit" loading={save.isPending}>{id ? '수정합니다' : '등록'}</Button>
          </div>
        </Form>

        <aside className="contract-pending-panel">
          <div className="contract-pending-head">
            <span>일정관리 등록</span>
            <Button size="small" className="contract-pending-btn" onClick={() => message.info('일정등록(데모)')}>일정등록</Button>
          </div>
          <div className="contract-pending-body">
            등록하실 일정관리가 없습니다.<br />(미수금, 할인, 미비서류, 정책약속 등)
          </div>
        </aside>
      </div>

      <Modal
        title="상품추가"
        open={productOpen}
        onCancel={() => setProductOpen(false)}
        footer={null}
        destroyOnHidden
        width={420}
      >
        <Form form={productForm} layout="vertical" onFinish={addProduct}>
          <Form.Item name="productId" label="상품" rules={[{ required: true, message: '상품을 선택하세요' }]}>
            <Select
              showSearch
              optionFilterProp="label"
              placeholder="- 선택 -"
              options={productOptions.map((o) => ({ value: o.value, label: o.label }))}
            />
          </Form.Item>
          <div className="product-modal-footer-right">
            <Button type="primary" htmlType="submit">추가</Button>
            <Button onClick={() => setProductOpen(false)}>취소</Button>
          </div>
        </Form>
      </Modal>
    </div>
  )
}
