/**
 * The shared ticket status board: the public pages behind a username the office
 * hands out, and the settings screen that issues them.
 *
 * Mirrors App\Support\Presenters\PublicTicketPresenter and
 * App\Http\Controllers\Settings\TicketStatusLinkController.
 */

export type TicketStatusTone = {
    value: string;
    label: string;
    color: string;
};

export type TicketStatusLink = {
    id: number;
    name: string;
    username: string;
    statuses: TicketStatusTone[];
    state: { value: 'active' | 'paused' | 'expired'; label: string; color: string };
    is_active: boolean;
    expires_at: string | null;
    last_used_at: string | null;
    last_used_ip: string | null;
    created_at: string | null;
    url: string;
};

export type TicketStatusOption = TicketStatusTone & {
    description: string;
    waiting_on: string;
    group: string;
    group_label: string;
};

export type IssuedStatusLink = {
    name: string;
    username: string;
    password: string;
    url: string;
};

export type TicketStatusLinksProps = {
    links: TicketStatusLink[];
    statuses: TicketStatusOption[];
    defaults: { days: number; landing_status: string; url: string };
    /** A password shown once, straight after issuing or re-issuing a link. */
    issued: IssuedStatusLink | null;
    /** What the board may do to a ticket, switched by an Admin or Super Admin. */
    board: { notes: boolean; review: boolean; complete: boolean };
    /** Whether the sign-in screen offers the staff email and password tab. */
    staff_login: boolean;
    can: { manage: boolean; manage_board: boolean };
};

export type PublicStatusLink = {
    id: number;
    name: string;
    username: string;
    statuses: Array<
        TicketStatusTone & { waiting_on: string; description: string }
    >;
    landing_status: string;
    expires_at: string | null;
};

/**
 * A crew's claim that the work is done, as the board shows it.
 *
 * `pending` means it is with the office; `sent_back` means there is something
 * still to answer, which is what the review note is for. Only an Admin or Super
 * Admin can turn a claim into a completed ticket.
 */
export type CompletionClaim = {
    id: number;
    state: {
        value: 'pending' | 'approved' | 'sent_back';
        label: string;
        tone: string;
        is_pending: boolean;
    };
    note: string;
    requested_by: string;
    requested_at: string | null;
    review_note: string | null;
    reviewed_by: string | null;
    reviewed_at: string | null;
};

export type PublicStatusTicket = {
    id: number;
    number: string;
    issue: string;
    status: TicketStatusTone & { waiting_on: string };
    priority: TicketStatusTone;
    customer: string | null;
    job_number: string | null;
    suburb: string | null;
    installer: string | null;
    owner: string | null;
    contact: string | null;
    phone: string | null;
    days_waiting: number;
    reported_at: string | null;
    status_changed_at: string | null;
    /** The last completion claim on this ticket, if anybody has made one. */
    completion: CompletionClaim | null;
};

/**
 * Who is reading the board. Staff arrive through their own CRM account and get
 * every queue their ticket access covers; a shared link carries the statuses the
 * office chose for it.
 */
export type TicketStatusViewer = {
    type: 'staff' | 'link';
    is_staff: boolean;
    name: string;
    role: string | null;
    username: string | null;
    statuses: Array<
        TicketStatusTone & { waiting_on: string; description: string }
    >;
    landing_status: string;
    expires_at: string | null;
};

export type TicketCompletionReviewRow = {
    id: number;
    ticket: PublicStatusTicket;
    claim: CompletionClaim;
    waiting_days: number;
};

export type TicketStatusBoardProps = {
    viewer: TicketStatusViewer;
    /** The issued link, when that is how the viewer got in. Null for staff. */
    link: PublicStatusLink | null;
    statuses: Array<
        TicketStatusTone & {
            description: string;
            waiting_on: string;
            count: number;
            is_current: boolean;
        }
    >;
    current: {
        value: string;
        label: string;
        description: string;
        waiting_on: string;
    };
    filters: { status: string; search: string };
    tickets: PublicStatusTicket[];
    totals: {
        waiting_on_installer: number;
        shown: number;
        oldest_days: number;
    };
    /**
     * What this reader may do, from who they are and which board actions the
     * office has left switched on.
     */
    can: { note: boolean; review: boolean; complete: boolean };
    /** The three switches as the office left them. */
    settings: { notes: boolean; review: boolean; complete: boolean };
    /** The kinds of outcome a reviewer may record, empty for everybody else. */
    resolutionOptions: Array<
        TicketStatusTone & { description: string }
    >;
    /** Claims waiting on an Admin or Super Admin, oldest first. */
    reviews: TicketCompletionReviewRow[];
};

export type TicketStatusLoginProps = {
    status: string | null;
    link: null;
    /** Off by default; switched in Settings -> Status link. */
    staff_login: boolean;
    /** A colleague already signed in whose account cannot read tickets. */
    staff_account: { name: string; role: string | null } | null;
};
