/**
 * 세금계산서 발행 서버 액션
 *
 * API Endpoints:
 * - GET /api/v1/tax-invoices - 목록 조회
 * - POST /api/v1/tax-invoices - 세금계산서 생성 (draft)
 * - POST /api/v1/tax-invoices/issue-direct - 생성 + 즉시 발행
 * - GET /api/v1/tax-invoices/{id} - 상세 조회
 * - GET /api/v1/tax-invoices/supplier-settings - 공급자 설정 조회
 * - PUT /api/v1/tax-invoices/supplier-settings - 공급자 설정 저장
 * - GET /api/v1/clients - 거래처 검색
 */

'use server';

import type { ActionResult } from '@/lib/api/execute-server-action';
import { executeServerAction } from '@/lib/api/execute-server-action';
import type { PaginatedActionResult } from '@/lib/api/execute-paginated-action';
import { executePaginatedAction } from '@/lib/api/execute-paginated-action';
import { buildApiUrl } from '@/lib/api/query-params';
import type {
  TaxInvoiceRecord,
  TaxInvoiceFormData,
  TaxInvoiceStatus,
  SupplierSettings,
  VendorSearchItem,
} from './types';

// ===== API → Frontend 변환 =====

interface TaxInvoiceApiData {
  id: number;
  nts_confirm_num: string | null;
  invoice_type: string;
  issue_type: string;
  direction: string;
  supplier_corp_num: string;
  supplier_corp_name: string;
  supplier_ceo_name: string | null;
  supplier_addr: string | null;
  supplier_biz_type: string | null;
  supplier_biz_class: string | null;
  supplier_contact_id: string | null;
  buyer_corp_num: string;
  buyer_corp_name: string;
  buyer_ceo_name: string | null;
  buyer_addr: string | null;
  buyer_biz_type: string | null;
  buyer_biz_class: string | null;
  buyer_contact_id: string | null;
  issue_date: string;
  supply_amount: string | number;
  tax_amount: string | number;
  total_amount: string | number;
  items: Array<Record<string, unknown>> | null;
  status: string;
  nts_send_status: string | null;
  issued_at: string | null;
  sent_at: string | null;
  cancelled_at: string | null;
  barobill_invoice_id: string | null;
  description: string | null;
  error_message: string | null;
  created_at: string;
}

function mapApiStatusToFrontend(status: string): TaxInvoiceStatus {
  switch (status) {
    case 'draft':
      return 'draft';
    case 'issued':
      return 'issued';
    case 'sent':
      return 'nts_sent';
    case 'failed':
    case 'cancelled':
      return 'error';
    default:
      return 'draft';
  }
}

function transformApiToFrontend(raw: TaxInvoiceApiData): TaxInvoiceRecord {
  return {
    id: String(raw.id),
    invoiceNumber: raw.nts_confirm_num || `TI-${raw.id}`,
    vendorName: raw.direction === 'sales' ? raw.buyer_corp_name : raw.supplier_corp_name,
    vendorBusinessNumber: raw.direction === 'sales' ? raw.buyer_corp_num : raw.supplier_corp_num,
    writeDate: raw.issue_date || '',
    sendDate: raw.sent_at || null,
    supplyAmount: Number(raw.supply_amount) || 0,
    taxAmount: Number(raw.tax_amount) || 0,
    totalAmount: Number(raw.total_amount) || 0,
    status: mapApiStatusToFrontend(raw.status),
  };
}

// ===== Frontend → API 변환 =====

function transformFrontendToApi(data: TaxInvoiceFormData): Record<string, unknown> {
  return {
    invoice_type: 'tax_invoice',
    issue_type: 'normal',
    direction: 'sales',
    supplier_corp_num: data.supplier.businessNumber,
    supplier_corp_name: data.supplier.companyName,
    supplier_ceo_name: data.supplier.representativeName || null,
    supplier_addr: data.supplier.address || null,
    supplier_biz_type: data.supplier.businessType || null,
    supplier_biz_class: data.supplier.businessItem || null,
    supplier_contact_id: data.supplier.contactEmail || null,
    buyer_corp_num: data.receiver.businessNumber,
    buyer_corp_name: data.receiver.companyName,
    buyer_ceo_name: data.receiver.representativeName || null,
    buyer_addr: data.receiver.address || null,
    buyer_biz_type: data.receiver.businessType || null,
    buyer_biz_class: data.receiver.businessItem || null,
    buyer_contact_id: data.receiver.contactEmail || null,
    issue_date: data.writeDate,
    supply_amount: data.items.reduce((s, i) => s + i.supplyAmount, 0),
    tax_amount: data.items.reduce((s, i) => s + i.taxAmount, 0),
    items: data.items
      .filter((i) => i.itemName)
      .map((item) => ({
        name: item.itemName,
        spec: item.specification,
        qty: item.quantity,
        unit_price: item.unitPrice,
        supply_amt: item.supplyAmount,
        tax_amt: item.taxAmount,
        remark: '',
      })),
    description: data.memo || null,
  };
}

// ===== 세금계산서 목록 조회 =====
export async function getTaxInvoices(params?: {
  page?: number;
  perPage?: number;
  dateType?: string;
  startDate?: string;
  endDate?: string;
  vendorSearch?: string;
  status?: string;
  sortBy?: string;
  sortOrder?: string;
}): Promise<PaginatedActionResult<TaxInvoiceRecord>> {
  return executePaginatedAction<TaxInvoiceApiData, TaxInvoiceRecord>({
    url: buildApiUrl('/api/v1/tax-invoices', {
      page: params?.page,
      per_page: params?.perPage,
      issue_date_from: params?.startDate,
      issue_date_to: params?.endDate,
      corp_name: params?.vendorSearch,
      status: params?.status !== 'all' ? params?.status : undefined,
    }),
    transform: transformApiToFrontend,
    errorMessage: '세금계산서 목록 조회에 실패했습니다.',
  });
}

// ===== 세금계산서 발행 (생성 + 즉시 발행) =====
export async function createTaxInvoice(
  data: TaxInvoiceFormData
): Promise<ActionResult<TaxInvoiceRecord>> {
  return executeServerAction<TaxInvoiceApiData, TaxInvoiceRecord>({
    url: buildApiUrl('/api/v1/tax-invoices/issue-direct'),
    method: 'POST',
    body: transformFrontendToApi(data),
    transform: transformApiToFrontend,
    errorMessage: '세금계산서 발행에 실패했습니다.',
  });
}

// ===== 공급자 설정 조회 =====
export async function getSupplierSettings(): Promise<ActionResult<SupplierSettings>> {
  return executeServerAction<Record<string, string | null>, SupplierSettings>({
    url: buildApiUrl('/api/v1/tax-invoices/supplier-settings'),
    transform: (data) => ({
      businessNumber: data.business_number || '',
      companyName: data.company_name || '',
      representativeName: data.representative_name || '',
      address: data.address || '',
      businessType: data.business_type || '',
      businessItem: data.business_item || '',
      contactName: data.contact_name || '',
      contactPhone: data.contact_phone || '',
      contactEmail: data.contact_email || '',
    }),
    errorMessage: '공급자 설정 조회에 실패했습니다.',
  });
}

// ===== 공급자 설정 저장 =====
export async function saveSupplierSettings(
  data: SupplierSettings
): Promise<ActionResult<SupplierSettings>> {
  return executeServerAction<Record<string, string | null>, SupplierSettings>({
    url: buildApiUrl('/api/v1/tax-invoices/supplier-settings'),
    method: 'PUT',
    body: {
      business_number: data.businessNumber,
      company_name: data.companyName,
      representative_name: data.representativeName,
      address: data.address,
      business_type: data.businessType,
      business_item: data.businessItem,
      contact_name: data.contactName,
      contact_phone: data.contactPhone,
      contact_email: data.contactEmail,
    },
    transform: (res) => ({
      businessNumber: res.business_number || '',
      companyName: res.company_name || '',
      representativeName: res.representative_name || '',
      address: res.address || '',
      businessType: res.business_type || '',
      businessItem: res.business_item || '',
      contactName: res.contact_name || '',
      contactPhone: res.contact_phone || '',
      contactEmail: res.contact_email || '',
    }),
    errorMessage: '공급자 설정 저장에 실패했습니다.',
  });
}

// ===== 세금계산서 상세 조회 =====
export async function getTaxInvoiceById(
  id: string
): Promise<
  ActionResult<TaxInvoiceFormData & { id: string; invoiceNumber: string; status: TaxInvoiceRecord['status'] }>
> {
  return executeServerAction<
    TaxInvoiceApiData,
    TaxInvoiceFormData & { id: string; invoiceNumber: string; status: TaxInvoiceRecord['status'] }
  >({
    url: buildApiUrl(`/api/v1/tax-invoices/${id}`),
    transform: (raw) => ({
      id: String(raw.id),
      invoiceNumber: raw.nts_confirm_num || `TI-${raw.id}`,
      status: mapApiStatusToFrontend(raw.status),
      supplier: {
        businessNumber: raw.supplier_corp_num || '',
        companyName: raw.supplier_corp_name || '',
        representativeName: raw.supplier_ceo_name || '',
        address: raw.supplier_addr || '',
        businessType: raw.supplier_biz_type || '',
        businessItem: raw.supplier_biz_class || '',
        contactName: '',
        contactPhone: '',
        contactEmail: raw.supplier_contact_id || '',
      },
      receiver: {
        businessNumber: raw.buyer_corp_num || '',
        companyName: raw.buyer_corp_name || '',
        representativeName: raw.buyer_ceo_name || '',
        address: raw.buyer_addr || '',
        businessType: raw.buyer_biz_type || '',
        businessItem: raw.buyer_biz_class || '',
        contactName: '',
        contactPhone: '',
        contactEmail: raw.buyer_contact_id || '',
      },
      writeDate: raw.issue_date || '',
      items: (raw.items || []).map((item, idx) => ({
        id: String(idx),
        month: '',
        day: '',
        itemName: String(item.name || ''),
        specification: String(item.spec || ''),
        quantity: Number(item.qty) || 0,
        unitPrice: Number(item.unit_price) || 0,
        supplyAmount: Number(item.supply_amt) || 0,
        taxAmount: Number(item.tax_amt) || 0,
        totalAmount: (Number(item.supply_amt) || 0) + (Number(item.tax_amt) || 0),
        taxType: 'taxable' as const,
      })),
      memo: raw.description || '',
    }),
    errorMessage: '세금계산서 조회에 실패했습니다.',
  });
}

// ===== 거래처 검색 (/api/v1/clients 연동) =====
interface ClientApiData {
  id: number;
  name: string;
  business_no: string;
  contact_person: string;
  address: string;
  business_type: string;
  business_item: string;
  manager_name: string;
  manager_tel: string;
  email: string;
}

export async function searchVendorsForTaxInvoice(
  query: string
): Promise<VendorSearchItem[]> {
  const result = await executeServerAction({
    url: buildApiUrl('/api/v1/clients', {
      q: query || undefined,
      only_active: true,
      size: 1000,
    }),
    transform: (data: { data: ClientApiData[] }) =>
      data.data.map((item) => ({
        id: String(item.id),
        companyName: item.name || '',
        businessNumber: item.business_no || '',
        representativeName: item.contact_person || '',
        address: item.address || '',
        businessType: item.business_type || '',
        businessItem: item.business_item || '',
        contactName: item.manager_name || '',
        contactPhone: item.manager_tel || '',
        contactEmail: item.email || '',
      })),
    errorMessage: '거래처 검색에 실패했습니다.',
  });
  return result.success ? (result.data ?? []) : [];
}
