import { useState, useCallback } from 'react';
import { Alert, Form, Input, Modal, Select, Space, Table, 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 PageContainer from '@/components/common/PageContainer';
import SearchForm from '@/components/common/SearchForm';
import DataGrid from '@/components/common/DataGrid';
import PermissionButton from '@/components/common/PermissionButton';
import {
  accountingCloseApi,
  AccountingCloseResp,
  AccountBalanceSnapshot,
  AccountingCloseSearchParam,
} from '@/api/accounting-close';
import { GRAY, RADIUS, SHADOW } from '@/theme/tokens';

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

const COLUMNS: ColDef<AccountingCloseResp>[] = [
  { field: 'closePeriod',     headerName: '결산기간',   width: 120, pinned: 'left' },
  { field: 'closeTypeName',   headerName: '결산구분',   width: 100 },
  { field: 'closeStatusName', headerName: '상태',       width: 100 },
  { field: 'journalPrefix',   headerName: '분개prefix', width: 120 },
  { field: 'journalCount',    headerName: '분개수',     width: 90,  type: 'numericColumn' },
  { field: 'totalDebit',      headerName: '차변합계',   flex: 1, type: 'numericColumn', valueFormatter: (p) => fmt(p.value) },
  { field: 'totalCredit',     headerName: '대변합계',   flex: 1, type: 'numericColumn', valueFormatter: (p) => fmt(p.value) },
  { field: 'closedAt',        headerName: '마감일시',   width: 150 },
  { field: 'reopenReason',    headerName: '재오픈사유', flex: 1 },
];

const SNAPSHOT_COLUMNS = [
  { title: '계정코드', dataIndex: 'accountCode', key: 'accountCode', width: 100 },
  { title: '계정명',   dataIndex: 'accountName', key: 'accountName' },
  { title: '구분',     dataIndex: 'accountType', key: 'accountType', width: 80 },
  { title: '차변합',   dataIndex: 'debitTotal',  key: 'debitTotal',  align: 'right' as const, render: fmt },
  { title: '대변합',   dataIndex: 'creditTotal', key: 'creditTotal', align: 'right' as const, render: fmt },
  { title: '잔액',     dataIndex: 'balance',     key: 'balance',     align: 'right' as const, render: fmt },
];

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

export default function AccountingCloseList() {
  const qc = useQueryClient();
  const [params, setParams] = useState<AccountingCloseSearchParam>({ pageSize: 200 });
  const [selectedRows, setSelectedRows] = useState<AccountingCloseResp[]>([]);
  const [draftOpen, setDraftOpen] = useState(false);
  const [reopenOpen, setReopenOpen] = useState(false);
  const [snapshots, setSnapshots] = useState<AccountBalanceSnapshot[] | null>(null);
  const [draftForm] = Form.useForm();
  const [reopenForm] = Form.useForm();

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

  const rows = data?.list ?? [];
  const selected = selectedRows[0];

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

  const handleCreateDraft = async () => {
    const values = await draftForm.validateFields();
    try {
      await accountingCloseApi.createDraft(values);
      message.success('결산 DRAFT 생성됨');
      qc.invalidateQueries({ queryKey: ['accounting-closes'] });
      setDraftOpen(false);
      draftForm.resetFields();
    } catch { /* request.ts 처리 */ }
  };

  const handleClose = () => {
    if (!selected) return;
    Modal.confirm({
      title: '결산 마감 실행',
      content: `${selected.closePeriod} (${selected.closeTypeName}) 을 마감하시겠습니까? 분개 채번 및 잔액 스냅샷이 생성됩니다.`,
      okText: '마감 실행',
      cancelText: '취소',
      onOk: async () => {
        try {
          await accountingCloseApi.close(selected.closeId);
          message.success('결산 마감 완료');
          qc.invalidateQueries({ queryKey: ['accounting-closes'] });
          setSelectedRows([]);
        } catch { /* request.ts 처리 */ }
      },
    });
  };

  const handleReopen = async () => {
    if (!selected) return;
    const values = await reopenForm.validateFields();
    try {
      await accountingCloseApi.reopen(selected.closeId, values.reopenReason);
      message.success('결산 재오픈됨');
      qc.invalidateQueries({ queryKey: ['accounting-closes'] });
      setReopenOpen(false);
      reopenForm.resetFields();
      setSelectedRows([]);
    } catch { /* request.ts 처리 */ }
  };

  const handleViewSnapshots = async () => {
    if (!selected) return;
    try {
      setSnapshots(await accountingCloseApi.snapshots(selected.closeId));
    } catch { /* request.ts 처리 */ }
  };

  return (
    <PageContainer
      title="회계 결산"
      description="월/분기/연 단위 회계 마감 및 계정과목별 잔액 스냅샷"
      extra={
        <Space>
          <PermissionButton menuCode="ACCOUNTING_CLOSE" permCode="READ"
            disabled={!selected} onClick={handleViewSnapshots}>
            잔액 스냅샷
          </PermissionButton>
          <PermissionButton menuCode="ACCOUNTING_CLOSE" permCode="CREATE"
            onClick={() => setDraftOpen(true)}>
            결산 생성
          </PermissionButton>
          <PermissionButton menuCode="ACCOUNTING_CLOSE" permCode="APPROVE"
            disabled={!selected} onClick={() => setReopenOpen(true)}>
            재오픈
          </PermissionButton>
          <PermissionButton menuCode="ACCOUNTING_CLOSE" permCode="EXECUTE"
            type="primary" disabled={!selected} onClick={handleClose}>
            마감 실행
          </PermissionButton>
        </Space>
      }
    >
      {isError && (
        <Alert type="warning" showIcon message="API 미응답"
          description="/api/accounting-closes 를 확인하세요." style={{ marginBottom: 16 }} />
      )}

      <SearchForm
        conditions={[
          { type: 'text', name: 'closePeriod', label: '결산기간', span: 6 },
          { type: 'text', name: 'closeType',   label: '구분(MONTHLY/QUARTERLY/YEARLY)', span: 8 },
          { type: 'text', name: 'closeStatus', label: '상태(DRAFT/CLOSED/REOPENED)', span: 8 },
        ]}
        onSearch={(v) => setParams({ ...v as AccountingCloseSearchParam, pageSize: 200 })}
        onReset={() => setParams({ pageSize: 200 })}
      />

      <ProCard style={cardStyle}>
        <DataGrid<AccountingCloseResp>
          rows={rows}
          columns={COLUMNS}
          loading={isLoading}
          height={520}
          rowKey="closeId"
          rowSelection="single"
          onSelectionChanged={handleSelectionChanged}
        />
      </ProCard>

      {/* 결산 DRAFT 생성 */}
      <Modal
        title="결산 DRAFT 생성"
        open={draftOpen}
        onOk={handleCreateDraft}
        onCancel={() => { setDraftOpen(false); draftForm.resetFields(); }}
        okText="생성"
        cancelText="취소"
      >
        <Form form={draftForm} layout="vertical" style={{ marginTop: 16 }}>
          <Form.Item name="closePeriod" label="결산기간"
            rules={[{ required: true, message: '결산기간을 입력하세요' }]}
            extra="월: YYYY-MM / 분기: YYYY-Q1 / 연: YYYY">
            <Input placeholder="예: 2025-03" />
          </Form.Item>
          <Form.Item name="closeType" label="결산구분"
            rules={[{ required: true, message: '결산구분을 선택하세요' }]}>
            <Select
              options={[
                { value: 'MONTHLY',   label: '월결산' },
                { value: 'QUARTERLY', label: '분기결산' },
                { value: 'YEARLY',    label: '연결산' },
              ]}
            />
          </Form.Item>
        </Form>
      </Modal>

      {/* 재오픈 */}
      <Modal
        title="결산 재오픈"
        open={reopenOpen}
        onOk={handleReopen}
        onCancel={() => { setReopenOpen(false); reopenForm.resetFields(); }}
        okText="재오픈"
        cancelText="취소"
      >
        <p>{selected?.closePeriod} ({selected?.closeTypeName}) 을 재오픈합니다.</p>
        <Form form={reopenForm} layout="vertical" style={{ marginTop: 16 }}>
          <Form.Item name="reopenReason" label="재오픈 사유"
            rules={[{ required: true, message: '재오픈 사유를 입력하세요' }]}>
            <Input.TextArea rows={3} placeholder="재오픈 사유" />
          </Form.Item>
        </Form>
      </Modal>

      {/* 잔액 스냅샷 */}
      <Modal
        title={`계정과목별 잔액 스냅샷 — ${selected?.closePeriod ?? ''}`}
        open={snapshots !== null}
        onCancel={() => setSnapshots(null)}
        footer={null}
        width={760}
      >
        <Table
          size="small"
          rowKey="snapshotId"
          columns={SNAPSHOT_COLUMNS}
          dataSource={snapshots ?? []}
          pagination={false}
        />
      </Modal>
    </PageContainer>
  );
}
