/**
 * Warranty and inspection reports, as the staff screens and the crew's public
 * form read them.
 *
 * The answers are a document rather than columns, so `InspectionData` is the
 * shape App\Support\InspectionAnswers writes and App\Support\InspectionChecklist
 * asks for. Every field is optional because a draft only has the ones that have
 * been filled in so far.
 */

export type InspectionStatusInfo = {
    value: string;
    label: string;
    color: string;
    /** Whether the crew can still answer through the link. */
    open: boolean;
};

export type InspectionOutcomeInfo = {
    value: string;
    label: string;
    full_label?: string;
    color: string;
};

export type InspectionPurposeInfo = {
    value: string;
    label: string;
    description?: string;
    color?: string;
};

export type InspectionSourceInfo = {
    value: string;
    label: string;
    color: string;
    description: string;
};

/** What a crew typed at the gate, before — or without — a client record. */
export type InspectionIntake = {
    customer_name: string | null;
    customer_phone: string | null;
    address: string | null;
    suburb: string | null;
    state: string | null;
    postcode: string | null;
};

/** A client the typed name and address found, offered for confirmation. */
export type InspectionIntakeCandidate = {
    id: number;
    customer_id: number;
    customer: string;
    phone: string | null;
    address: string;
    suburb: string;
    state: string;
    postcode: string;
    job: { job_number: string; title: string | null } | null;
    reason: string;
    score: number;
};

export type InspectionIntakeFormProps = {
    purposes: Array<{ value: string; label: string; description: string }>;
    states: Array<{ value: string; label: string }>;
    /** What was typed before a reload, so nothing has to be retyped. */
    intake: Record<string, string | null> | null;
    urls: { start: string };
};

export type InspectionConfirmProps = {
    intake: Record<string, string | null>;
    candidates: InspectionIntakeCandidate[];
    purposes: Array<{ value: string; label: string; description: string }>;
    states: Array<{ value: string; label: string }>;
    urls: { back: string; link: string };
};

import type { Paginated, TicketCustomerOption, TicketJobOption } from './crm';

export type InspectionSummary = {
    id: number;
    reference: string;
    purpose: InspectionPurposeInfo;
    source: InspectionSourceInfo;
    status: InspectionStatusInfo;
    outcome: InspectionOutcomeInfo | null;
    job: { id: number; job_number: string; title?: string | null } | null;
    customer: { id: number; name: string } | null;
    site: { address: string; suburb: string; state: string } | null;
    installer: { id: number; name: string } | null;
    inspector_name: string | null;
    inspector_licence: string | null;
    inspected_on: string | null;
    system_kw: number | null;
    defect_count: number;
    photo_count: number | null;
    sent_at: string | null;
    submitted_at: string | null;
    reviewed_at: string | null;
    expires_at: string | null;
    created_at: string | null;
    /** Whether a client record (or a job) stands behind the report. */
    client_linked: boolean;
};

export type InspectionDefect = {
    severity: 'minor' | 'major' | 'critical' | string;
    title: string;
    description?: string | null;
    action?: string | null;
    due?: string | null;
    section?: string | null;
};

export type InspectionData = {
    system?: {
        type?: string | null;
        kw?: string | null;
        modules?: string | null;
        inverter?: string | null;
        battery?: string | null;
        serials?: string | null;
        installed_on?: string | null;
        monitoring?: string | null;
    };
    site?: {
        switchboard?: string | null;
        meter_number?: string | null;
        nmi?: string | null;
        dnsp?: string | null;
        phase?: 'single' | 'three' | string | null;
        roof_type?: string | null;
        roof_condition?: 'good' | 'fair' | 'poor' | string | null;
        tilt?: string | null;
        azimuth?: string | null;
        access_notes?: string | null;
    };
    answers?: Record<string, Record<string, 'pass' | 'fail' | 'na' | string>>;
    item_notes?: Record<string, Record<string, string>>;
    measurements?: Record<string, string>;
    defects?: InspectionDefect[];
    findings?: string | null;
    recommendations?: string | null;
    customer?: { name?: string | null; comment?: string | null };
    declaration?: {
        name?: string | null;
        company?: string | null;
        licence?: string | null;
        date?: string | null;
        agreed?: boolean;
    };
    outcome?: string | null;
    review?: { note?: string | null; by?: string; at?: string };
};

export type InspectionChecklistSection = {
    key: string;
    title: string;
    standard: string;
    intro: string;
    battery_only: boolean;
    items: Array<{ key: string; label: string; hint: string | null }>;
};

export type InspectionChecklist = {
    sections: InspectionChecklistSection[];
    measurements: Record<
        string,
        { label: string; unit: string; hint: string | null }
    >;
    system_types: Array<{ value: string; label: string }>;
    outcomes: Array<{
        value: string;
        label: string;
        description: string;
        color: string;
    }>;
    severities: Array<{ value: string; label: string; description: string }>;
};

export type InspectionAttachment = {
    id: number;
    name: string;
    caption: string | null;
    kind: string;
    label: string;
    mime_type: string | null;
    size: number | null;
    human_size: string;
    is_image: boolean;
    is_pdf?: boolean;
    is_word?: boolean;
    url: string;
    download_url?: string;
    delete_url?: string;
    created_at?: string | null;
};

export type InspectionJobDetail = {
    id: number;
    job_number: string;
    title: string | null;
    status: { value: string; label: string; color: string };
    installer: string | null;
    customer: {
        id: number;
        name: string;
        phone: string | null;
        email: string | null;
    } | null;
    site: {
        address: string;
        suburb: string;
        state: string;
        postcode: string;
        nmi: string | null;
        meter_number: string | null;
        dnsp: string | null;
        phase: string;
        roof: string | null;
        access_notes: string | null;
    } | null;
};

export type InspectionSystemDetail = {
    size_kw: string | null;
    panel_count: number | null;
    panel: string;
    inverter: string;
    inverter_serial: string | null;
    battery: string;
    battery_capacity_kwh: string | null;
    saa_installer_number: string | null;
    saa_designer_number: string | null;
};

export type InspectionDetail = InspectionSummary & {
    data: InspectionData | null;
    intake: InspectionIntake;
    client: {
        id: number;
        name: string;
        phone: string | null;
        email: string | null;
    } | null;
    share_url: string;
    checklist: InspectionChecklist;
    link_days_left: number | null;
    creator: { id: number; name: string } | null;
    reviewer: { id: number; name: string } | null;
    attachments: InspectionAttachment[];
    job: InspectionJobDetail | null;
    system: InspectionSystemDetail;
};

export type InspectionIndexProps = {
    reports: Paginated<InspectionSummary>;
    filters: {
        search: string | null;
        status: string;
        purpose: string | null;
        outcome: string | null;
        installer: number | null;
        source: string | null;
        client: string | null;
    };
    filterOptions: {
        statuses: Array<{ value: string; label: string }>;
        purposes: Array<{ value: string; label: string; description: string }>;
        outcomes: Array<{ value: string; label: string }>;
        installers: Array<{
            value: number;
            label: string;
            note?: string | null;
        }>;
        sources: Array<{ value: string; label: string; description: string }>;
        clients: Array<{ value: string; label: string }>;
    };
    /** The standing link crews open on site. The address only for its managers. */
    intake: {
        open: boolean;
        url: string | null;
        token: string | null;
        can_manage: boolean;
    };
    counts: {
        open: number;
        awaiting_review: number;
        defects: number;
        failed: number;
        unlinked: number;
    };
    can: { create: boolean };
};

export type InspectionFormProps = {
    purposes: Array<{ value: string; label: string; description: string }>;
    installers: Array<{ value: number; label: string; note?: string | null }>;
    /** The job the form was opened from, with its customer, when there is one. */
    preselectedJob: TicketJobOption | null;
    preselectedCustomer: TicketCustomerOption | null;
    /** The standard checklist, summarised: what the crew will actually be asked. */
    sections: Array<{
        key: string;
        title: string;
        standard: string;
        items: number;
        battery_only: boolean;
    }>;
    /** The standing link a crew can start a report from on site. */
    intake: InspectionIndexProps['intake'];
    can: { create: boolean };
};

/** The report as the crew's public form reads it. */
export type PublicInspection = {
    reference: string;
    purpose: { value: string; label: string; description: string };
    source: { value: string; label: string };
    intake: InspectionIntake & { summary: string | null };
    status: InspectionStatusInfo;
    is_open: boolean;
    expires_at: string | null;
    sent_at: string | null;
    submitted_at: string | null;
    data: InspectionData | null;
    prefill: InspectionData & {
        system: NonNullable<InspectionData['system']>;
        site: NonNullable<InspectionData['site']>;
        customer: NonNullable<InspectionData['customer']>;
        declaration: NonNullable<InspectionData['declaration']>;
    };
    job: {
        job_number: string | null;
        title: string | null;
        customer: string | null;
        installer: string | null;
        site: {
            address: string;
            suburb: string;
            state: string;
            postcode: string;
            nmi: string | null;
            meter_number: string | null;
            dnsp: string | null;
            phase: string;
            roof_type: string | null;
            access_notes: string | null;
        } | null;
    };
    checklist: InspectionChecklist;
    urls: { submit: string; draft: string; files: string };
    attachments: InspectionAttachment[];
    limits: { photos: number; documents: number; kilobytes: number };
};
