import { NextRequest, NextResponse } from 'next/server'
import { getIronSession } from 'iron-session'
import { sessionOptions } from '@/libs/session'
import { cookies } from 'next/headers'
import type { SessionData } from '@/types/Auth'
import { HttpStatusCode } from 'axios'
import { loggerWrapper } from '@/libs/api-wrapper'
import { SurveySalesService } from '../service'
import { ApiError } from 'next/dist/server/api-utils'
import { SurveyBasicInfo } from '@/types/Survey'

/**
 * @api {GET} /api/survey-sales/:id 조사 매물 조회 API
 * @apiName GET /api/survey-sales/:id
 * @apiGroup SurveySales
 * @apiDescription 조사 매물 조회 API
 *
 * @apiParam {Number} id 조사 매물 PRIMARY KEY ID (required)
 * @apiParam {Boolean} isPdf pdf 데이터 조회 여부 (optional, default: false)
 *
 * @apiSuccess {Object} SurveySaleBasicInfo 조사 매물 기본 정보 | Blob 파일
 *
 * @apiError {Number} 401 세션 정보 없음 (로그인 필요)
 * @apiError {Number} 403 권한 없음
 * @apiError {Number} 404 조사 매물 없음
 * @apiError {Number} 500 서버 오류
 *
 * @apiExample {curl} Example usage:
 *     curl -X GET \
 *       -G "isPdf=true" \
 *       http://localhost:3000/api/survey-sales/1
 *
 * @apiSuccessExample {json} Success-Response:
 *     {
 *       "id": 1,
 *       "srlNo": "1234567890",
 *       "storeId": "1234567890",
 *       "detailInfo": {
 *         "id": 1,
 *         "trestleMfpcCd": "1234567890",
 *         "trestleManufacturerProductName": "1234567890",
 *         "memo": "1234567890"
 *         ...
 *       }
 *       ...
 *     }
 */
async function getSurveySaleDetail(request: NextRequest): Promise<NextResponse> {
  const cookieStore = await cookies()
  const session = await getIronSession<SessionData>(cookieStore, sessionOptions)
  const id = request.nextUrl.pathname.split('/').pop() ?? ''
  const { searchParams } = new URL(request.url)
  const isPdf = searchParams.get('isPdf') === 'true'

  const service = new SurveySalesService({}, session)
  const result = await service.tryFunction(() => service.fetchSurvey(Number(id), isPdf))
  if (result instanceof ApiError) {
    return NextResponse.json({ error: result.message }, { status: result.statusCode })
  }
  if (isPdf) {
    const pdfBlob = await service.createSurveyPdf(result as SurveyBasicInfo)
    if (pdfBlob instanceof ApiError) {
      return NextResponse.json({ error: pdfBlob.message }, { status: pdfBlob.statusCode })
    }
    return new NextResponse(pdfBlob, {
      headers: {
        'Content-Type': 'application/pdf',
        'Content-Disposition': `attachment; filename=${result.SRL_NO}.pdf; filename*=UTF-8''${encodeURIComponent(result.SRL_NO)}.pdf`,
      },
    })
  }
  return NextResponse.json(result)
}

/**
 * @api {POST} /api/survey-sales/:id 조사 매물 수정, 삭제, 제출 API
 * @apiName POST /api/survey-sales/:id
 * @apiGroup SurveySales
 * @apiDescription 조사 매물 수정, 삭제, 제출 API
 *
 * @apiParam {String} method 요청 메서드 (PUT, DELETE, PATCH) (required)
 * @apiParam {Object} body 요청 본문 (required)
 *
 * @apiSuccess {NextResponse} 요청 처리 결과
 * @apiError {Number} 400 잘못된 요청
 */
async function methodHandler(request: NextRequest): Promise<NextResponse> {
  const id = request.nextUrl.pathname.split('/').pop() ?? ''
  const body = await request.json()

  switch (body.method) {
    case 'PUT':
      return updateSurveySaleDetail(id, body)
    case 'DELETE':
      return deleteSurveySaleDetail(id)
    case 'PATCH':
      return submitSurveySaleDetail(id, body)
    default:
      return NextResponse.json({ error: 'Invalid method' }, { status: HttpStatusCode.BadRequest })
  }
}

/**
 * @api {PUT} /api/survey-sales/:id 조사 매물 수정 API
 * @apiName PUT /api/survey-sales/:id
 * @apiGroup SurveySales
 * @apiDescription 조사 매물 수정 API
 *
 * @apiParam {Number} id 조사 매물 PRIMARY KEY ID (required)
 * @apiBody {Object} survey 조사 매물 데이터 (required)
 * @apiBody {Boolean} isTemporary 임시 저장 여부 (optional, default: false)
 * @apiBody {String} storeId 판매점 ID (optional)
 * @apiBody {String} role 권한 (optional)
 *
 * @apiSuccess {Object} SurveySaleBasicInfo 수정된 조사 매물 기본 정보
 *
 * @apiExample {curl} Example usage:
 *     curl -X PUT \
 *       -H "Content-Type: application/json" \
 *       -d '{"survey": {"detailInfo": {"id": 1, "memo": "1234567890", ...}, "srlNo": "1234567890", ...},"storeId": "1234567890", "role": "T01", "isTemporary": false}' \
 *       http://localhost:3000/api/survey-sales/1
 *
 * @apiSuccessExample {json} Success-Response:
 *     {
 *       "id": 1,
 *       "srlNo": "1234567890",
 *       "storeId": "1234567890",
 *       "detailInfo": {
 *         "id": 1,
 *         "memo": "1234567890",
 *         ...
 *       }
 *       ...
 *     }
 * */
async function updateSurveySaleDetail(id: string, body: any): Promise<NextResponse> {
  const service = new SurveySalesService({})

  const result = await service.tryFunction(() => service.updateSurvey(Number(id), body.survey, body.isTemporary, body.storeId, body.role))
  if (result instanceof ApiError) {
    return NextResponse.json({ error: result.message }, { status: result.statusCode })
  }
  return NextResponse.json(result)
}

/**
 * @api {DELETE} /api/survey-sales/:id 조사 매물 삭제 API
 * @apiName DELETE /api/survey-sales/:id
 * @apiGroup SurveySales
 * @apiDescription 조사 매물 삭제 API
 *
 * @apiParam {Number} id 조사 매물 PRIMARY KEY ID (required)
 *
 * @apiSuccess {String} message 삭제 성공 메시지
 *
 * @apiExample {curl} Example usage:
 *     curl -X DELETE \
 *       http://localhost:3000/api/survey-sales/1
 *
 * @apiSuccessExample {json} Success-Response:
 *     {
 *       "message": "success"
 */
async function deleteSurveySaleDetail(id: string): Promise<NextResponse> {
  const service = new SurveySalesService({})
  const result = await service.tryFunction(() => service.deleteSurvey(Number(id)))
  if (result instanceof ApiError) {
    return NextResponse.json({ error: result.message }, { status: result.statusCode })
  }
  return NextResponse.json({ status: HttpStatusCode.Ok })
}

/**
 * @api {PATCH} /api/survey-sales/:id 조사 매물 제출 API
 * @apiName PATCH /api/survey-sales/:id
 * @apiGroup SurveySales
 * @apiDescription 조사 매물 제출 API
 *
 * @apiParam {Number} id 조사 매물 PRIMARY KEY ID (required)
 * @apiBody {String} targetId 제출 대상 ID (required)
 * @apiBody {String} targetNm 제출 대상 이름 (required)
 *
 * @apiSuccess {String} message 제출 성공 메시지
 * @apiSuccess {Object} data 제출된 조사 매물 기본 정보
 *
 * @apiExample {curl} Example usage:
 *     curl -X PATCH \
 *       -H "Content-Type: application/json" \
 *       -d '{"targetId": "1234567890", "targetNm": "1234567890"}' \
 *       http://localhost:3000/api/survey-sales/1
 *
 * @apiSuccessExample {json} Success-Response:
 *     {
 *       "message": "success",
 *       "data": {
 *         "id": 1,
 *         "srlNo": "1234567890",
 *         "storeId": "1234567890",
 *         "detailInfo": {
 *           "id": 1,
 *           "memo": "1234567890",
 *           ...
 *         }
 *         ...
 *       }
 *     }
 */
async function submitSurveySaleDetail(id: string, body: any): Promise<NextResponse> {
  const service = new SurveySalesService({})

  const result = await service.tryFunction(() => service.submitSurvey(Number(id), body.targetId, body.targetNm))
  if (result instanceof ApiError) {
    return NextResponse.json({ error: result.message }, { status: result.statusCode })
  }
  return NextResponse.json({ status: HttpStatusCode.Ok, data: result })
}

export const GET = loggerWrapper(getSurveySaleDetail)
export const POST = loggerWrapper(methodHandler)
