<?php

namespace App\Http\Controllers\Api\Admin\HR;

use App\Http\Controllers\Controller;
use App\Services\HR\BusinessIncomePaymentService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Style\Alignment;
use PhpOffice\PhpSpreadsheet\Style\Border;
use PhpOffice\PhpSpreadsheet\Style\Color;
use PhpOffice\PhpSpreadsheet\Style\Fill;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use Symfony\Component\HttpFoundation\StreamedResponse;

class BusinessIncomePaymentController extends Controller
{
    private const ALLOWED_PAYROLL_USERS = ['이경호', '전진선', '김보곤'];

    public function __construct(
        private BusinessIncomePaymentService $service
    ) {}

    private function checkPayrollAccess(): ?JsonResponse
    {
        if (! in_array(auth()->user()->name, self::ALLOWED_PAYROLL_USERS)) {
            return response()->json([
                'success' => false,
                'message' => '급여관리는 관계자만 볼 수 있습니다.',
            ], 403);
        }

        return null;
    }

    /**
     * 사업소득 지급 목록 (HTMX → 스프레드시트 파셜)
     */
    public function index(Request $request): JsonResponse|Response
    {
        if ($denied = $this->checkPayrollAccess()) {
            return $denied;
        }

        $year = $request->integer('year') ?: now()->year;
        $month = $request->integer('month') ?: now()->month;

        $earners = $this->service->getActiveEarners();
        $payments = $this->service->getPayments($year, $month);
        $stats = $this->service->getMonthlyStats($year, $month);

        $earnersForJs = $earners->map(fn ($e) => [
            'user_id' => $e->user_id,
            'business_name' => $e->business_name ?? ($e->user?->name ?? ''),
            'user_name' => $e->user?->name ?? '',
            'business_reg_number' => $e->business_registration_number ?? '',
        ])->values();

        if ($request->header('HX-Request')) {
            return response(
                view('hr.business-income-payments.partials.stats', compact('stats')).
                '<!-- SPLIT -->'.
                view('hr.business-income-payments.partials.spreadsheet', compact('payments', 'earnersForJs', 'year', 'month'))
            );
        }

        return response()->json([
            'success' => true,
            'data' => $payments,
            'stats' => $stats,
        ]);
    }

    /**
     * 일괄 저장
     */
    public function bulkSave(Request $request): JsonResponse
    {
        if ($denied = $this->checkPayrollAccess()) {
            return $denied;
        }

        $validated = $request->validate([
            'year' => 'required|integer|min:2020|max:2100',
            'month' => 'required|integer|min:1|max:12',
            'items' => 'present|array',
            'items.*.payment_id' => 'nullable|integer',
            'items.*.user_id' => 'nullable|integer',
            'items.*.display_name' => 'required|string|max:100',
            'items.*.business_reg_number' => 'nullable|string|max:20',
            'items.*.gross_amount' => 'required|numeric|min:0',
            'items.*.service_content' => 'nullable|string|max:200',
            'items.*.payment_date' => 'nullable|date',
            'items.*.note' => 'nullable|string|max:500',
        ]);

        $result = $this->service->bulkSave(
            $validated['year'],
            $validated['month'],
            $validated['items']
        );

        return response()->json([
            'success' => true,
            'message' => "저장 {$result['saved']}건, 삭제 {$result['deleted']}건, 건너뜀 {$result['skipped']}건",
            'data' => $result,
        ]);
    }

    /**
     * XLSX 내보내기 (스타일링 포함)
     */
    public function export(Request $request): StreamedResponse|JsonResponse
    {
        if ($denied = $this->checkPayrollAccess()) {
            return $denied;
        }

        $year = $request->integer('year') ?: now()->year;
        $month = $request->integer('month') ?: now()->month;

        $payments = $this->service->getExportData($year, $month);
        $filename = "사업소득자임금대장_{$year}년{$month}월_".now()->format('Ymd').'.xlsx';

        $spreadsheet = new Spreadsheet;
        $sheet = $spreadsheet->getActiveSheet();
        $sheet->setTitle('사업소득자 임금대장');

        $lastCol = 'K';
        $headers = ['구분', '상호/성명', "사업자등록번호\n/주민등록번호", '용역내용', '지급총액', "소득세\n(3%)", "지방소득세\n(0.3%)", '공제합계', '실지급액', '지급일자', '비고'];

        // ── Row 1: 제목 ──
        $sheet->mergeCells("A1:{$lastCol}1");
        $sheet->setCellValue('A1', "< {$year}년도 {$month}월 사업소득자 임금대장 >");
        $sheet->getStyle('A1')->applyFromArray([
            'font' => ['bold' => true, 'size' => 14],
            'alignment' => ['horizontal' => Alignment::HORIZONTAL_CENTER, 'vertical' => Alignment::VERTICAL_CENTER],
        ]);
        $sheet->getRowDimension(1)->setRowHeight(30);

        // ── Row 2: 헤더 ──
        foreach ($headers as $colIdx => $header) {
            $cell = chr(65 + $colIdx).'2';
            $sheet->setCellValue($cell, $header);
        }
        $sheet->getStyle("A2:{$lastCol}2")->applyFromArray([
            'font' => ['bold' => true, 'size' => 10, 'color' => ['argb' => 'FFFFFFFF']],
            'fill' => ['fillType' => Fill::FILL_SOLID, 'startColor' => ['argb' => 'FF1F3864']],
            'alignment' => ['horizontal' => Alignment::HORIZONTAL_CENTER, 'vertical' => Alignment::VERTICAL_CENTER, 'wrapText' => true],
            'borders' => ['allBorders' => ['borderStyle' => Border::BORDER_THIN, 'color' => ['argb' => 'FF000000']]],
        ]);
        $sheet->getRowDimension(2)->setRowHeight(36);

        // ── Row 3~: 데이터 ──
        $dataStartRow = 3;
        $row = $dataStartRow;
        $moneyColumns = ['E', 'F', 'G', 'H', 'I'];

        foreach ($payments as $idx => $payment) {
            $name = $payment->display_name ?: ($payment->user?->name ?? '-');
            $regNumber = $payment->business_reg_number ?? '';

            $sheet->setCellValue("A{$row}", $idx + 1);
            $sheet->setCellValue("B{$row}", $name);
            $sheet->setCellValueExplicit("C{$row}", $regNumber, \PhpOffice\PhpSpreadsheet\Cell\DataType::TYPE_STRING);
            $sheet->setCellValue("D{$row}", $payment->service_content ?? '');
            $sheet->setCellValue("E{$row}", (int) $payment->gross_amount);
            $sheet->setCellValue("F{$row}", (int) $payment->income_tax);
            $sheet->setCellValue("G{$row}", (int) $payment->local_income_tax);
            $sheet->setCellValue("H{$row}", (int) $payment->total_deductions);
            $sheet->setCellValue("I{$row}", (int) $payment->net_amount);
            $sheet->setCellValue("J{$row}", $payment->payment_date?->format('Y-m-d') ?? '');
            $sheet->setCellValue("K{$row}", $payment->note ?? '');

            // 지급일자 빨간색
            if ($payment->payment_date) {
                $sheet->getStyle("J{$row}")->getFont()->setColor(new Color('FF0000'));
            }

            $row++;
        }

        // 빈 행 채움 (최소 10행)
        $minEndRow = $dataStartRow + 9;
        while ($row <= $minEndRow) {
            $row++;
        }
        $lastDataRow = $row - 1;

        // ── 데이터 영역 스타일 ──
        $dataRange = "A{$dataStartRow}:{$lastCol}{$lastDataRow}";
        $sheet->getStyle($dataRange)->applyFromArray([
            'borders' => ['allBorders' => ['borderStyle' => Border::BORDER_THIN, 'color' => ['argb' => 'FF000000']]],
            'alignment' => ['vertical' => Alignment::VERTICAL_CENTER],
            'font' => ['size' => 10],
        ]);

        // 가운데 정렬: 구분, 용역내용, 지급일자, 비고
        foreach (['A', 'D', 'J', 'K'] as $col) {
            $sheet->getStyle("{$col}{$dataStartRow}:{$col}{$lastDataRow}")
                ->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER);
        }

        // 금액 서식: #,##0 + 오른쪽 정렬
        foreach ($moneyColumns as $col) {
            $range = "{$col}{$dataStartRow}:{$col}{$lastDataRow}";
            $sheet->getStyle($range)->getNumberFormat()->setFormatCode('#,##0');
            $sheet->getStyle($range)->getAlignment()->setHorizontal(Alignment::HORIZONTAL_RIGHT);
        }

        // ── 열 너비 ──
        $widths = ['A' => 8, 'B' => 14, 'C' => 22, 'D' => 14, 'E' => 14, 'F' => 14, 'G' => 14, 'H' => 14, 'I' => 14, 'J' => 14, 'K' => 14];
        foreach ($widths as $col => $width) {
            $sheet->getColumnDimension($col)->setWidth($width);
        }

        // ── 응답 반환 ──
        return response()->streamDownload(function () use ($spreadsheet) {
            $writer = new Xlsx($spreadsheet);
            $writer->save('php://output');
            $spreadsheet->disconnectWorksheets();
        }, $filename, [
            'Content-Type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
            'Cache-Control' => 'max-age=0',
        ]);
    }
}
