'use client' import { useMemo, type ReactNode } from 'react' import { Input } from '@/components/ui/input' import { Label } from '@/components/ui/label' import { CalendarDays } from 'lucide-react' import { monthsBetween, parseDateParts, validatePeriodDuration, } from '@/lib/bookkeeping/validate-period-duration' import type { EntityType } from '@/types' const monthNames = [ 'januari', 'februari', 'mars', 'april', 'maj', 'juni', 'juli', 'augusti', 'september', 'oktober', 'november', 'december', ] function formatSwedishDate(dateStr: string): string { const { year, month, day } = parseDateParts(dateStr) return `${day} ${monthNames[month - 1]} ${year}` } function endsOnDec31(end: string): boolean { const e = parseDateParts(end) return e.month === 12 && e.day === 31 } /** * Map validatePeriodDuration's English messages to user-facing Swedish copy. */ function toSwedishError(msg: string): string { if (msg.includes('after period start')) return 'Slutdatum måste vara efter startdatum.' if (msg.includes('1st of a month')) return 'Startdatum måste vara den första i månaden.' if (msg.includes('last day of a month')) return 'Slutdatum måste vara den sista i månaden.' if (msg.includes('exceeds maximum 18 months')) return 'Räkenskapsåret får vara högst 18 månader (BFL 3 kap.).' if (msg.includes('at least 6 months')) return 'Första räkenskapsåret måste vara minst 6 månader (BFL 3 kap.).' return msg } export interface FiscalPeriodValidation { /** User-facing Swedish error, or null if valid */ error: string | null /** Integer month count, or null if inputs are incomplete/invalid */ months: number | null /** True if inputs are complete enough to render the summary */ canSummarise: boolean } /** * Shared validation for the first fiscal period — used by both onboarding Step 3 * and the settings FiscalPeriodEditor. Returns Swedish error copy. */ export function validateFirstPeriod( startDate: string, endDate: string, entityType: EntityType | undefined ): FiscalPeriodValidation { if (!startDate || !endDate) { return { error: null, months: null, canSummarise: false } } if (endDate <= startDate) { return { error: 'Slutdatum måste vara efter startdatum.', months: null, canSummarise: false, } } const baseError = validatePeriodDuration(startDate, endDate, { isFirstPeriod: true }) if (baseError) { return { error: toSwedishError(baseError), months: monthsBetween(startDate, endDate), canSummarise: true, } } if (entityType === 'enskild_firma' && !endsOnDec31(endDate)) { return { error: 'Enskild firma måste ha slutdatum 31 december (BFL 3 kap.).', months: monthsBetween(startDate, endDate), canSummarise: true, } } return { error: null, months: monthsBetween(startDate, endDate), canSummarise: true, } } interface FiscalPeriodDateFieldsProps { startDate: string onStartDateChange: (value: string) => void startHelpText?: string /** * Render the end-date control. Onboarding passes its AB end-month ; settings passes a native . */ endDateSlot: ReactNode /** The raw end-date string (used for summary + validation). */ endDate: string entityType: EntityType | undefined /** Label for the summary card. Defaults to "Ditt första räkenskapsår". */ summaryTitle?: string /** Optional override for start date