import { useState } from 'react';
import {
  Card, Col, Empty, Form, Input, InputNumber, Modal,
  Row, Select, Space, Table, Tag, Typography, message,
} from 'antd';
import {
  DeleteOutlined, EditOutlined, PlusOutlined, ReloadOutlined,
} from '@ant-design/icons';
import { useQuery, useQueryClient } from '@tanstack/react-query';
import PageContainer from '@/components/common/PageContainer';
import PermissionButton from '@/components/common/PermissionButton';
import { commonCodeApi, CommonCodeGroup, CommonCode } from '@/api/user';

const { Text } = Typography;
const MENU = 'SYSTEM_CODE';

/* ------------------------------------------------------------------ */
/*  내부 상태 타입                                                       */
/* ------------------------------------------------------------------ */
type GroupModalState =
  | { open: false }
  | { open: true; mode: 'create' }
  | { open: true; mode: 'edit'; group: CommonCodeGroup };

type CodeModalState =
  | { open: false }
  | { open: true; mode: 'create' }
  | { open: true; mode: 'edit'; code: CommonCode };

/* ------------------------------------------------------------------ */
/*  메인 컴포넌트                                                        */
/* ------------------------------------------------------------------ */
export default function CodeList() {
  const qc = useQueryClient();

  /* 선택 그룹 & 검색어 */
  const [selected, setSelected] = useState<CommonCodeGroup | null>(null);
  const [keyword, setKeyword] = useState('');

  /* 모달 상태 */
  const [groupModal, setGroupModal] = useState<GroupModalState>({ open: false });
  const [codeModal, setCodeModal] = useState<CodeModalState>({ open: false });

  /* 폼 인스턴스 */
  const [groupForm] = Form.useForm();
  const [codeForm] = Form.useForm();

  /* 로딩 상태 */
  const [groupSaving, setGroupSaving] = useState(false);
  const [codeSaving, setCodeSaving] = useState(false);

  /* ---------------------------------------------------------------- */
  /*  쿼리                                                              */
  /* ---------------------------------------------------------------- */
  const { data: groups = [], isFetching: groupLoading } = useQuery({
    queryKey: ['code', 'groups', keyword],
    queryFn: () => commonCodeApi.groups(keyword || undefined),
  });

  const { data: codes = [], isFetching: codeLoading } = useQuery({
    queryKey: ['code', 'codes', selected?.groupCode],
    queryFn: () => commonCodeApi.codes(selected!.groupCode),
    enabled: !!selected,
  });

  /* ---------------------------------------------------------------- */
  /*  공통 리로드                                                       */
  /* ---------------------------------------------------------------- */
  const invalidateGroups = () => qc.invalidateQueries({ queryKey: ['code', 'groups'] });
  const invalidateCodes = (gc: string) =>
    qc.invalidateQueries({ queryKey: ['code', 'codes', gc] });

  /* ---------------------------------------------------------------- */
  /*  그룹 모달 열기                                                    */
  /* ---------------------------------------------------------------- */
  const openGroupCreate = () => {
    groupForm.resetFields();
    groupForm.setFieldsValue({ isSystem: 'N', sortOrder: 0 });
    setGroupModal({ open: true, mode: 'create' });
  };

  const openGroupEdit = (group: CommonCodeGroup) => {
    groupForm.resetFields();
    groupForm.setFieldsValue({
      groupCode: group.groupCode,
      groupName: group.groupName,
      description: group.description,
      isSystem: group.isSystem,
      sortOrder: group.sortOrder,
    });
    setGroupModal({ open: true, mode: 'edit', group });
  };

  /* ---------------------------------------------------------------- */
  /*  그룹 저장                                                         */
  /* ---------------------------------------------------------------- */
  const handleGroupSave = async () => {
    if (!groupModal.open) return;
    try {
      setGroupSaving(true);
      const values = await groupForm.validateFields();

      if (groupModal.mode === 'create') {
        await commonCodeApi.createGroup(values);
        message.success('그룹이 추가되었습니다.');
      } else {
        const { group } = groupModal;
        await commonCodeApi.updateGroup(group.groupCode, {
          groupName: values.groupName,
          description: values.description,
        });
        message.success('그룹이 수정되었습니다.');
        // 선택된 그룹 이름 동기화
        if (selected?.groupCode === group.groupCode) {
          setSelected((prev) =>
            prev ? { ...prev, groupName: values.groupName, description: values.description } : null,
          );
        }
        await commonCodeApi.refreshCache(group.groupCode);
      }

      await invalidateGroups();
      setGroupModal({ open: false });
    } catch {
      // validateFields 실패 시 폼 에러 표시 — 별도 처리 불필요
    } finally {
      setGroupSaving(false);
    }
  };

  /* ---------------------------------------------------------------- */
  /*  그룹 삭제                                                         */
  /* ---------------------------------------------------------------- */
  const confirmDeleteGroup = (group: CommonCodeGroup) => {
    Modal.confirm({
      title: '그룹 삭제',
      content: (
        <span>
          <b>{group.groupName}</b> 그룹과 하위 코드를 모두 삭제합니다.
          <br />계속하시겠습니까?
        </span>
      ),
      okText: '삭제',
      okType: 'danger',
      cancelText: '취소',
      onOk: async () => {
        await commonCodeApi.deleteGroup(group.groupCode);
        message.success('그룹이 삭제되었습니다.');
        if (selected?.groupCode === group.groupCode) setSelected(null);
        await commonCodeApi.refreshCache(group.groupCode);
        invalidateGroups();
      },
    });
  };

  /* ---------------------------------------------------------------- */
  /*  코드 모달 열기                                                    */
  /* ---------------------------------------------------------------- */
  const openCodeCreate = () => {
    codeForm.resetFields();
    codeForm.setFieldsValue({ isActive: 'Y', sortOrder: 0 });
    setCodeModal({ open: true, mode: 'create' });
  };

  const openCodeEdit = (code: CommonCode) => {
    codeForm.resetFields();
    codeForm.setFieldsValue({
      code: code.code,
      codeName: code.codeName,
      codeDesc: code.codeDesc,
      sortOrder: code.sortOrder,
      isActive: code.isActive,
    });
    setCodeModal({ open: true, mode: 'edit', code });
  };

  /* ---------------------------------------------------------------- */
  /*  코드 저장                                                         */
  /* ---------------------------------------------------------------- */
  const handleCodeSave = async () => {
    if (!codeModal.open || !selected) return;
    try {
      setCodeSaving(true);
      const values = await codeForm.validateFields();

      if (codeModal.mode === 'create') {
        await commonCodeApi.createCode(selected.groupCode, values);
        message.success('코드가 추가되었습니다.');
      } else {
        await commonCodeApi.updateCode(codeModal.code.codeId, values);
        message.success('코드가 수정되었습니다.');
      }

      await commonCodeApi.refreshCache(selected.groupCode);
      invalidateCodes(selected.groupCode);
      setCodeModal({ open: false });
    } catch {
      // 폼 검증 실패 — 별도 처리 불필요
    } finally {
      setCodeSaving(false);
    }
  };

  /* ---------------------------------------------------------------- */
  /*  코드 삭제                                                         */
  /* ---------------------------------------------------------------- */
  const confirmDeleteCode = (code: CommonCode) => {
    Modal.confirm({
      title: '코드 삭제',
      content: (
        <span>
          코드 <b>{code.code} ({code.codeName})</b>을(를) 삭제합니다.
          <br />계속하시겠습니까?
        </span>
      ),
      okText: '삭제',
      okType: 'danger',
      cancelText: '취소',
      onOk: async () => {
        await commonCodeApi.deleteCode(code.codeId);
        message.success('코드가 삭제되었습니다.');
        if (selected) {
          await commonCodeApi.refreshCache(selected.groupCode);
          invalidateCodes(selected.groupCode);
        }
      },
    });
  };

  /* ---------------------------------------------------------------- */
  /*  렌더                                                              */
  /* ---------------------------------------------------------------- */
  return (
    <PageContainer title="공통코드 관리">
      <Row gutter={16}>
        {/* ======================================================= */}
        {/* 왼쪽: 그룹 목록                                          */}
        {/* ======================================================= */}
        <Col span={10}>
          <Card
            size="small"
            title="코드 그룹"
            extra={
              <Space size={4}>
                <PermissionButton
                  menuCode={MENU}
                  permCode="CREATE"
                  type="primary"
                  size="small"
                  icon={<PlusOutlined />}
                  onClick={openGroupCreate}
                >
                  그룹 추가
                </PermissionButton>
                <PermissionButton
                  menuCode={MENU}
                  permCode="READ"
                  size="small"
                  icon={<ReloadOutlined />}
                  onClick={invalidateGroups}
                />
              </Space>
            }
          >
            <Input.Search
              placeholder="그룹코드 / 그룹명 검색"
              allowClear
              size="small"
              style={{ marginBottom: 8 }}
              onSearch={(v) => setKeyword(v)}
              onChange={(e) => { if (!e.target.value) setKeyword(''); }}
            />
            <Table<CommonCodeGroup>
              rowKey="groupCode"
              dataSource={groups}
              loading={groupLoading}
              size="small"
              pagination={false}
              scroll={{ y: 520 }}
              onRow={(r) => ({
                onClick: () => setSelected(r),
                style: { cursor: 'pointer' },
              })}
              rowClassName={(r) =>
                r.groupCode === selected?.groupCode ? 'ant-table-row-selected' : ''
              }
              columns={[
                { title: '그룹코드', dataIndex: 'groupCode', width: 140, ellipsis: true },
                { title: '그룹명', dataIndex: 'groupName', ellipsis: true },
                {
                  title: '유형',
                  dataIndex: 'isSystem',
                  width: 68,
                  align: 'center',
                  render: (v: string) =>
                    v === 'Y' ? (
                      <Tag color="orange" style={{ margin: 0, fontSize: 11 }}>시스템</Tag>
                    ) : (
                      <Tag style={{ margin: 0, fontSize: 11 }}>일반</Tag>
                    ),
                },
                {
                  title: '작업',
                  key: 'actions',
                  width: 72,
                  align: 'center',
                  render: (_, r) => (
                    <Space size={2} onClick={(e) => e.stopPropagation()}>
                      <PermissionButton
                        menuCode={MENU}
                        permCode="UPDATE"
                        type="text"
                        size="small"
                        icon={<EditOutlined />}
                        onClick={() => openGroupEdit(r)}
                      />
                      <PermissionButton
                        menuCode={MENU}
                        permCode="DELETE"
                        type="text"
                        size="small"
                        danger
                        disabled={r.isSystem === 'Y'}
                        icon={<DeleteOutlined />}
                        onClick={() => confirmDeleteGroup(r)}
                      />
                    </Space>
                  ),
                },
              ]}
            />
          </Card>
        </Col>

        {/* ======================================================= */}
        {/* 오른쪽: 코드 목록                                         */}
        {/* ======================================================= */}
        <Col span={14}>
          <Card
            size="small"
            title={selected ? `코드 목록 — ${selected.groupName}` : '코드 목록'}
            extra={
              selected && (
                <PermissionButton
                  menuCode={MENU}
                  permCode="CREATE"
                  type="primary"
                  size="small"
                  icon={<PlusOutlined />}
                  onClick={openCodeCreate}
                >
                  코드 추가
                </PermissionButton>
              )
            }
          >
            {!selected ? (
              <Empty description="왼쪽에서 그룹을 선택하세요" style={{ padding: '40px 0' }} />
            ) : (
              <>
                <Table<CommonCode>
                  rowKey="codeId"
                  dataSource={codes}
                  loading={codeLoading}
                  size="small"
                  pagination={false}
                  scroll={{ y: 520 }}
                  columns={[
                    { title: '코드', dataIndex: 'code', width: 120, ellipsis: true },
                    { title: '코드명', dataIndex: 'codeName', width: 130, ellipsis: true },
                    { title: '설명', dataIndex: 'codeDesc', ellipsis: true },
                    { title: '정렬', dataIndex: 'sortOrder', width: 52, align: 'right' },
                    {
                      title: '활성',
                      dataIndex: 'isActive',
                      width: 60,
                      align: 'center',
                      render: (v: string) =>
                        v === 'Y' ? (
                          <Tag color="green" style={{ margin: 0 }}>Y</Tag>
                        ) : (
                          <Tag style={{ margin: 0 }}>N</Tag>
                        ),
                    },
                    {
                      title: '작업',
                      key: 'actions',
                      width: 72,
                      align: 'center',
                      render: (_, r) => (
                        <Space size={2}>
                          <PermissionButton
                            menuCode={MENU}
                            permCode="UPDATE"
                            type="text"
                            size="small"
                            icon={<EditOutlined />}
                            onClick={() => openCodeEdit(r)}
                          />
                          <PermissionButton
                            menuCode={MENU}
                            permCode="DELETE"
                            type="text"
                            size="small"
                            danger
                            icon={<DeleteOutlined />}
                            onClick={() => confirmDeleteCode(r)}
                          />
                        </Space>
                      ),
                    },
                  ]}
                />
                {selected.isSystem === 'Y' && (
                  <Text type="warning" style={{ display: 'block', marginTop: 8, fontSize: 12 }}>
                    시스템 그룹의 코드는 식별자 변경·삭제가 제한됩니다.
                  </Text>
                )}
              </>
            )}
          </Card>
        </Col>
      </Row>

      {/* ========================================================= */}
      {/* 그룹 추가 / 수정 모달                                       */}
      {/* ========================================================= */}
      <Modal
        title={groupModal.open && groupModal.mode === 'create' ? '그룹 추가' : '그룹 수정'}
        open={groupModal.open}
        onOk={handleGroupSave}
        onCancel={() => setGroupModal({ open: false })}
        okText={groupModal.open && groupModal.mode === 'create' ? '추가' : '수정'}
        cancelText="취소"
        confirmLoading={groupSaving}
        destroyOnClose
        width={480}
      >
        <Form form={groupForm} layout="vertical" style={{ marginTop: 16 }}>
          <Form.Item
            name="groupCode"
            label="그룹코드"
            rules={[
              { required: true, message: '그룹코드를 입력하세요' },
              { pattern: /^[A-Z0-9_]+$/, message: '영문 대문자, 숫자, 밑줄만 사용 가능합니다' },
            ]}
          >
            <Input
              placeholder="예) AGENT_STATUS"
              disabled={groupModal.open && groupModal.mode === 'edit'}
            />
          </Form.Item>
          <Form.Item
            name="groupName"
            label="그룹명"
            rules={[{ required: true, message: '그룹명을 입력하세요' }]}
          >
            <Input placeholder="예) 설계사 상태" />
          </Form.Item>
          <Form.Item name="description" label="설명">
            <Input.TextArea rows={2} placeholder="그룹에 대한 설명을 입력하세요" />
          </Form.Item>
          {groupModal.open && groupModal.mode === 'create' && (
            <Row gutter={12}>
              <Col span={12}>
                <Form.Item name="isSystem" label="시스템 여부">
                  <Select options={[{ value: 'Y', label: '시스템' }, { value: 'N', label: '일반' }]} />
                </Form.Item>
              </Col>
              <Col span={12}>
                <Form.Item name="sortOrder" label="정렬 순서">
                  <InputNumber min={0} style={{ width: '100%' }} />
                </Form.Item>
              </Col>
            </Row>
          )}
        </Form>
      </Modal>

      {/* ========================================================= */}
      {/* 코드 추가 / 수정 모달                                       */}
      {/* ========================================================= */}
      <Modal
        title={codeModal.open && codeModal.mode === 'create' ? '코드 추가' : '코드 수정'}
        open={codeModal.open}
        onOk={handleCodeSave}
        onCancel={() => setCodeModal({ open: false })}
        okText={codeModal.open && codeModal.mode === 'create' ? '추가' : '수정'}
        cancelText="취소"
        confirmLoading={codeSaving}
        destroyOnClose
        width={460}
      >
        <Form form={codeForm} layout="vertical" style={{ marginTop: 16 }}>
          <Form.Item
            name="code"
            label="코드값"
            rules={[
              { required: true, message: '코드값을 입력하세요' },
              { pattern: /^[A-Z0-9_]+$/, message: '영문 대문자, 숫자, 밑줄만 사용 가능합니다' },
            ]}
          >
            <Input
              placeholder="예) ACTIVE"
              disabled={codeModal.open && codeModal.mode === 'edit'}
            />
          </Form.Item>
          <Form.Item
            name="codeName"
            label="코드명"
            rules={[{ required: true, message: '코드명을 입력하세요' }]}
          >
            <Input placeholder="예) 활성" />
          </Form.Item>
          <Form.Item name="codeDesc" label="설명">
            <Input.TextArea rows={2} placeholder="코드에 대한 설명을 입력하세요" />
          </Form.Item>
          <Row gutter={12}>
            <Col span={12}>
              <Form.Item name="sortOrder" label="정렬 순서">
                <InputNumber min={0} style={{ width: '100%' }} />
              </Form.Item>
            </Col>
            <Col span={12}>
              <Form.Item name="isActive" label="활성 여부">
                <Select
                  options={[
                    { value: 'Y', label: '활성' },
                    { value: 'N', label: '비활성' },
                  ]}
                />
              </Form.Item>
            </Col>
          </Row>
        </Form>
      </Modal>
    </PageContainer>
  );
}
