import {
  Controller,
  Get,
  Post,
  Put,
  Body,
  Query,
  Param,
  UseGuards,
  ParseIntPipe,
  Res,
} from '@nestjs/common';
import { Response } from 'express';
import { ApiTags, ApiOperation, ApiBearerAuth } from '@nestjs/swagger';
import { FaxService } from './fax.service';
import { UpdateFaxConfigDto, CancelFaxDto } from './fax.dto';
import { AdminJwtAuthGuard } from '../auth/admin/jwt.guard';
import { RolesGuard } from '../auth/admin/roles.guard';
import { Roles } from '../auth/admin/roles.decorator';

@ApiTags('관리자 - FAX')
@ApiBearerAuth()
@UseGuards(AdminJwtAuthGuard, RolesGuard)
@Roles('admin')
@Controller('admin/fax')
export class FaxAdminController {
  constructor(private readonly faxService: FaxService) {}

  @Get('config')
  @ApiOperation({ summary: 'FAX 설정 조회' })
  async getFaxConfig() {
    return this.faxService.getFaxConfig();
  }

  @Put('config')
  @ApiOperation({ summary: 'FAX 설정 수정' })
  async updateFaxConfig(@Body() dto: UpdateFaxConfigDto) {
    return this.faxService.updateFaxConfig(dto.pointPerPage, dto.apiUsageAmount);
  }

  @Get('history')
  @ApiOperation({ summary: 'FAX 발송 내역 조회' })
  async getFaxHistoryList(@Query() query: any) {
    // searchKey/searchText 방식 처리
    let memLoginId = query.memLoginId;
    let fxhBatchId = query.fxhBatchId;
    let fxhFaxCode = query.fxhFaxCode;

    if (query.searchKey && query.searchText) {
      if (query.searchKey === 'memLoginId') {
        memLoginId = query.searchText;
      } else if (query.searchKey === 'fxhBatchId') {
        fxhBatchId = query.searchText;
      } else if (query.searchKey === 'fxhFaxCode') {
        fxhFaxCode = query.searchText;
      }
    }

    return this.faxService.getFaxHistoryList({
      page: query.page ? parseInt(query.page, 10) : 1,
      limit: query.limit ? parseInt(query.limit, 10) : 20,
      status: query.fxhStatus || query.status,
      requestStatus: query.fxhRequestStatus,
      deliveryStatus: query.fxhDeliveryStatus,
      memId: query.memId ? parseInt(query.memId, 10) : undefined,
      sagId: query.sagId ? parseInt(query.sagId, 10) : undefined,
      agcId: query.agcId ? parseInt(query.agcId, 10) : undefined,
      memType: query.memType,
      sendType: query.sendType,
      memLoginId,
      fxhBatchId,
      fxhFaxCode,
      startDate: query.startDate,
      endDate: query.endDate,
    });
  }

  @Get('history/download')
  @ApiOperation({ summary: 'FAX 발송 내역 엑셀 다운로드' })
  async downloadFaxHistory(@Query() query: any, @Res() res: Response) {
    // searchKey/searchText 방식 처리
    let memLoginId = query.memLoginId;
    let fxhBatchId = query.fxhBatchId;
    let fxhFaxCode = query.fxhFaxCode;

    if (query.searchKey && query.searchText) {
      if (query.searchKey === 'memLoginId') {
        memLoginId = query.searchText;
      } else if (query.searchKey === 'fxhBatchId') {
        fxhBatchId = query.searchText;
      } else if (query.searchKey === 'fxhFaxCode') {
        fxhFaxCode = query.searchText;
      }
    }

    const data = await this.faxService.getFaxHistoryForExcel({
      status: query.fxhStatus || query.status,
      requestStatus: query.fxhRequestStatus,
      deliveryStatus: query.fxhDeliveryStatus,
      memId: query.memId ? parseInt(query.memId, 10) : undefined,
      sagId: query.sagId ? parseInt(query.sagId, 10) : undefined,
      agcId: query.agcId ? parseInt(query.agcId, 10) : undefined,
      memType: query.memType,
      sendType: query.sendType,
      memLoginId,
      fxhBatchId,
      fxhFaxCode,
      startDate: query.startDate,
      endDate: query.endDate,
    });

    // 상태 변환
    const getStatusLabel = (status: string | null) => {
      switch (status) {
        case 'SUCCESS': return '성공';
        case 'FAILED': return '실패';
        case 'PENDING': return '대기중';
        default: return status || '-';
      }
    };

    // 회원타입 변환
    const getMemberTypeLabel = (type: string | null) => {
      switch (type) {
        case 'MEM001': return '일반';
        case 'MEM002': return '기업';
        default: return type || '-';
      }
    };

    // ExcelJS Workbook 직접 사용 (스타일링 적용을 위해)
    const ExcelJS = require('exceljs');
    const workbook = new ExcelJS.Workbook();
    const worksheet = workbook.addWorksheet('FAX내역');

    // 컬럼 설정
    worksheet.columns = [
      { header: '영업대리점명', key: '영업대리점명', width: 15 },
      { header: '영업채널명', key: '영업채널명', width: 15 },
      { header: '회원타입', key: '회원타입', width: 10 },
      { header: '기업명', key: '기업명', width: 15 },
      { header: '청구방식', key: '청구방식', width: 10 },
      { header: '회원아이디', key: '회원아이디', width: 15 },
      { header: '고객명', key: '고객명', width: 15 },
      { header: '청구서번호', key: '청구서번호', width: 20 },
      { header: '발송요청번호', key: '발송요청번호', width: 20 },
      { header: '보험사', key: '보험사', width: 15 },
      { header: '발송요청상태', key: '발송요청상태', width: 12 },
      { header: '발송완료상태', key: '발송완료상태', width: 12 },
      { header: '발송수', key: '발송수', width: 10 },
      { header: '차감머니액', key: '차감머니액', width: 12 },
      { header: '발송실패사유', key: '발송실패사유', width: 20 },
      { header: '발송완료일', key: '발송완료일', width: 18 },
      { header: '등록일', key: '등록일', width: 18 },
    ];

    // 첫 번째 행 스타일 (머니관리와 동일)
    worksheet.getRow(1).font = { bold: true };
    worksheet.getRow(1).fill = {
      type: 'pattern',
      pattern: 'solid',
      fgColor: { argb: 'FFD9D9D9' },
    };

    // 데이터 추가
    for (const item of data) {
      worksheet.addRow({
        영업대리점명: item.sagName || '미소속',
        영업채널명: item.sacName || '해당없음',
        회원타입: getMemberTypeLabel(item.memType),
        기업명: item.agcCorporateName || '-',
        청구방식: 'FAX',
        회원아이디: item.memLoginId,
        고객명: item.ivhName || '-',
        청구서번호: item.fxhBatchId || '-',
        발송요청번호: item.fxhFaxCode || '-',
        보험사: item.fxhReceiverName,
        발송요청상태: getStatusLabel(item.fxhRequestStatus),
        발송완료상태: getStatusLabel(item.fxhDeliveryStatus),
        발송수: item.fxhPageCount,
        차감머니액: item.fxhPointUsed,
        발송실패사유: item.fxhFailureReason || '-',
        발송완료일: item.fxhCompletedAt,
        등록일: item.fxhCreatedAt,
      });
    }

    const filename = `FAX_내역_${new Date().toISOString().slice(0,10)}.xlsx`;
    const encodedFilename = encodeURIComponent(filename);
    res.set({
      'Content-Type': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
      'Content-Disposition': `attachment; filename*=UTF-8''${encodedFilename}`,
    });

    const buffer = await workbook.xlsx.writeBuffer();
    res.send(buffer);
  }

  @Get('history/:id')
  @ApiOperation({ summary: 'FAX 발송 내역 상세 조회' })
  async getFaxHistoryDetail(@Param('id', ParseIntPipe) id: number) {
    return this.faxService.getFaxHistoryDetail(id);
  }

  @Post('cancel')
  @ApiOperation({ summary: 'FAX 포인트 취소' })
  async cancelFaxPoint(@Body() dto: CancelFaxDto) {
    return this.faxService.cancelFaxPoint(dto.fxhId);
  }

  @Post('resend')
  @ApiOperation({ summary: 'FAX 재발송' })
  async resendFax(@Body() dto: { fxhId: number }) {
    return this.faxService.resendFax(dto.fxhId);
  }

  @Get('status/:jobId')
  @ApiOperation({ summary: 'FAX 발송 상태 조회 (jobId 기준)' })
  async getFaxStatus(@Param('jobId') jobId: string) {
    return this.faxService.getFaxStatus(jobId);
  }

  @Get('history/:fxhId/status')
  @ApiOperation({ summary: '✅ FAX 발송 내역의 최신 상태 조회 (fxhId 기준)' })
  async getFaxHistoryStatus(@Param('fxhId', ParseIntPipe) fxhId: number) {
    const history = await this.faxService.getFaxHistoryDetail(fxhId);

    if (!history.fxhFaxCode) {
      throw new Error('팩스 발송 코드(jobId)가 없습니다.');
    }

    return this.faxService.getFaxStatus(history.fxhFaxCode);
  }

  @Get('invoice/:ivhId/files')
  @ApiOperation({ summary: '청구서 파일 목록 조회' })
  async getInvoiceFiles(@Param('ivhId', ParseIntPipe) ivhId: number) {
    const files = await this.faxService.getInvoiceFiles(ivhId);

    // attachmentFiles 배열 처리
    const attachments = Array.isArray(files.attachmentFiles) ? files.attachmentFiles : [];

    return {
      invoiceFiles: files.invoiceFiles,
      attachmentFiles: attachments,
    };
  }

}
