import { useState, useCallback } from 'react';
import { Alert, Form, Input, Modal, Space, message } from 'antd';
import { ProCard } from '@ant-design/pro-components';
import { useQuery, useQueryClient } from '@tanstack/react-query';
import type { ColDef, SelectionChangedEvent } from '@ag-grid-community/core';
import dayjs from 'dayjs';
import PageContainer from '@/components/common/PageContainer';
import SearchForm from '@/components/common/SearchForm';
import DataGrid from '@/components/common/DataGrid';
import PermissionButton from '@/components/common/PermissionButton';
import { accountingApi, AccountingJournalResp, AccountingSearchParam } from '@/api/accounting';
import { GRAY, RADIUS, SHADOW } from '@/theme/tokens';

const fmt = (v: unknown) => (v as number)?.toLocaleString() ?? '-';

const COLUMNS: ColDef<AccountingJournalResp>[] = [
  { field: 'journalNo',    headerName: '분개번호',   width: 140, pinned: 'left', rowGroup: false },
  { field: 'settleMonth',  headerName: '정산월',     width: 100 },
  { field: 'agentName',    headerName: '설계사',     width: 120 },
  { field: 'contractNo',   headerName: '계약번호',   width: 140 },
  { field: 'accountCode',  headerName: '계정코드',   width: 110 },
  { field: 'accountName',  headerName: '계정명',     width: 150 },
  { field: 'debitAmount',  headerName: '차변',       flex: 1, type: 'numericColumn', valueFormatter: (p) => fmt(p.value) },
  { field: 'creditAmount', headerName: '대변',       flex: 1, type: 'numericColumn', valueFormatter: (p) => fmt(p.value) },
  { field: 'description',  headerName: '적요',       flex: 1 },
  { field: 'statusName',   headerName: '상태',       width: 90 },
  { field: 'closedAt',     headerName: '마감일시',   width: 140 },
];

const cardStyle = { background: '#fff', borderRadius: RADIUS.lg, border: `1px solid ${GRAY[100]}`, boxShadow: SHADOW.sm };

export default function AccountingJournalList() {
  const qc = useQueryClient();
  const currentMonth = dayjs().format('YYYYMM');
  const [params, setParams] = useState<AccountingSearchParam>({
    settleMonth: currentMonth,
    pageSize: 500,
  });
  const [selectedRows, setSelectedRows] = useState<AccountingJournalResp[]>([]);
  const [closeModalOpen, setCloseModalOpen] = useState(false);
  const [generateModalOpen, setGenerateModalOpen] = useState(false);
  const [closeForm] = Form.useForm();

  const { data, isLoading, isError } = useQuery({
    queryKey: ['accounting-journals', params],
    queryFn: () => accountingApi.list(params),
    retry: false,
  });

  const rows = data?.list ?? [];

  const handleSelectionChanged = useCallback((e: SelectionChangedEvent<AccountingJournalResp>) => {
    setSelectedRows(e.api.getSelectedRows());
  }, []);

  const handleGenerate = async () => {
    try {
      await accountingApi.generate({ settleMonth: params.settleMonth ?? currentMonth });
      message.success('분개 생성 완료');
      qc.invalidateQueries({ queryKey: ['accounting-journals'] });
      setGenerateModalOpen(false);
    } catch { /* request.ts 처리 */ }
  };

  const handleClose = async () => {
    const values = await closeForm.validateFields();
    const ids = selectedRows.map((r) => r.entryId);
    try {
      await accountingApi.close({ journalNo: values.journalNo, entryIds: ids });
      message.success('마감 완료');
      qc.invalidateQueries({ queryKey: ['accounting-journals'] });
      setCloseModalOpen(false);
      closeForm.resetFields();
      setSelectedRows([]);
    } catch { /* request.ts 처리 */ }
  };

  return (
    <PageContainer
      title="회계 분개장"
      description="정산 회계 분개 엔트리 관리"
      extra={
        <Space>
          <PermissionButton
            menuCode="ACCOUNTING_JOURNAL"
            permCode="CREATE"
            onClick={() => setGenerateModalOpen(true)}
          >
            분개 생성
          </PermissionButton>
          <PermissionButton
            menuCode="ACCOUNTING_JOURNAL"
            permCode="APPROVE"
            type="primary"
            disabled={selectedRows.length === 0}
            onClick={() => setCloseModalOpen(true)}
          >
            마감 ({selectedRows.length}건)
          </PermissionButton>
        </Space>
      }
    >
      {isError && (
        <Alert
          type="warning"
          showIcon
          message="API 미응답"
          description="/api/accounting-journals 를 확인하세요."
          style={{ marginBottom: 16 }}
        />
      )}

      <SearchForm
        conditions={[
          { type: 'month', name: 'settleMonth', label: '정산월',   span: 6 },
          { type: 'text',  name: 'journalNo',   label: '분개번호', span: 6 },
          { type: 'text',  name: 'agentName',   label: '설계사명', span: 6 },
        ]}
        onSearch={(v) => setParams({ ...v as AccountingSearchParam, pageSize: 500 })}
        onReset={() => setParams({ settleMonth: currentMonth, pageSize: 500 })}
      />

      <ProCard style={cardStyle}>
        <DataGrid<AccountingJournalResp>
          rows={rows}
          columns={COLUMNS}
          loading={isLoading}
          height={620}
          rowKey="entryId"
          rowSelection="multiple"
          onSelectionChanged={handleSelectionChanged}
        />
      </ProCard>

      {/* 분개 생성 확인 모달 */}
      <Modal
        title="분개 생성"
        open={generateModalOpen}
        onOk={handleGenerate}
        onCancel={() => setGenerateModalOpen(false)}
        okText="생성"
        cancelText="취소"
      >
        <p>{params.settleMonth} 정산월의 회계 분개를 생성하시겠습니까?</p>
      </Modal>

      {/* 마감 처리 모달 */}
      <Modal
        title="분개 마감"
        open={closeModalOpen}
        onOk={handleClose}
        onCancel={() => { setCloseModalOpen(false); closeForm.resetFields(); }}
        okText="마감"
        cancelText="취소"
      >
        <p>선택한 {selectedRows.length}건의 분개를 마감합니다.</p>
        <Form form={closeForm} layout="vertical" style={{ marginTop: 16 }}>
          <Form.Item
            name="journalNo"
            label="분개번호 (journal_no)"
            rules={[{ required: true, message: '분개번호를 입력하세요' }]}
          >
            <Input placeholder="예: JNL-2024-001" />
          </Form.Item>
        </Form>
      </Modal>
    </PageContainer>
  );
}
