import { Form, Head, router } from '@inertiajs/react';
import { useState } from 'react';

import HeadingSmall from '@/components/heading-small';
import { SortableHeader, useSort } from '@/components/sortable-header';
import {
    Dialog,
    DialogContent,
    DialogDescription,
    DialogHeader,
    DialogTitle,
    DialogTrigger,
} from '@/components/ui/dialog';
import AppLayout from '@/layouts/app-layout';
import { destroy, index, store, update } from '@/routes/admin/standard-offer-rates';

type TouRates = {
    on_peak: number | null;
    off_peak: number | null;
    shoulder: number | null;
};

type Rate = {
    id: number;
    utility_id: number;
    utility: {
        id: number;
        name: string;
        code: string;
        state: { code: string } | null;
    } | null;
    rate_class: string;
    rate_structure: string;
    effective_date: string;
    expiration_date: string | null;
    rate: string | null;
    tou_rates: TouRates | null;
    notes: string | null;
};

type EnumOption = { value: string; label: string };

type Utility = { id: number; name: string; code: string };

type Filters = { utility_id: string };

type Props = {
    rates: Rate[];
    utilities: Utility[];
    rateClasses: EnumOption[];
    rateStructures: EnumOption[];
    filters: Filters;
};

const breadcrumbs = [{ title: 'Standard Offer Rates', href: index.url() }];

const inputClasses =
    'rounded-md border border-zinc-200 bg-white px-3 py-2 text-sm dark:border-zinc-800 dark:bg-zinc-950';
const selectClasses =
    'rounded-md border border-zinc-200 bg-white px-3 py-2 text-sm shadow-sm dark:border-zinc-800 dark:bg-zinc-950 dark:text-zinc-100';
const labelClasses = 'text-xs font-medium text-zinc-700 dark:text-zinc-300';
const errorClasses = 'text-xs text-red-600';

function formatRate(rate: Rate): string {
    if (rate.rate_structure === 'tou' && rate.tou_rates) {
        const parts = [`On-peak: ${rate.tou_rates.on_peak}`, `Off-peak: ${rate.tou_rates.off_peak}`];
        if (rate.tou_rates.shoulder != null) {
            parts.push(`Shoulder: ${rate.tou_rates.shoulder}`);
        }
        return parts.join(' / ');
    }
    return rate.rate ? rate.rate : '—';
}

function formatLabel(value: string): string {
    return value
        .replace(/_/g, ' ')
        .replace(/\b\w/g, (c) => c.toUpperCase());
}

function RateFormFields({
    rate,
    utilities,
    rateClasses,
    rateStructures,
    errors,
}: {
    rate?: Rate;
    utilities: Utility[];
    rateClasses: EnumOption[];
    rateStructures: EnumOption[];
    errors: Record<string, string>;
}) {
    const [structure, setStructure] = useState(rate?.rate_structure ?? 'flat');
    const isTou = structure === 'tou';

    return (
        <div className="grid grid-cols-1 gap-3">
            <div className="flex flex-col gap-1">
                <label className={labelClasses}>Utility</label>
                <select name="utility_id" defaultValue={rate?.utility_id ?? ''} className={selectClasses}>
                    <option value="">Select a utility…</option>
                    {utilities.map((u) => (
                        <option key={u.id} value={u.id}>
                            {u.name}
                        </option>
                    ))}
                </select>
                {errors.utility_id && <div className={errorClasses}>{errors.utility_id}</div>}
            </div>

            <div className="grid grid-cols-2 gap-3">
                <div className="flex flex-col gap-1">
                    <label className={labelClasses}>Rate Class</label>
                    <select name="rate_class" defaultValue={rate?.rate_class ?? ''} className={selectClasses}>
                        <option value="">Select…</option>
                        {rateClasses.map((c) => (
                            <option key={c.value} value={c.value}>
                                {formatLabel(c.value)}
                            </option>
                        ))}
                    </select>
                    {errors.rate_class && <div className={errorClasses}>{errors.rate_class}</div>}
                </div>

                <div className="flex flex-col gap-1">
                    <label className={labelClasses}>Rate Structure</label>
                    <select
                        name="rate_structure"
                        defaultValue={rate?.rate_structure ?? 'flat'}
                        onChange={(e) => setStructure(e.target.value)}
                        className={selectClasses}
                    >
                        {rateStructures.map((s) => (
                            <option key={s.value} value={s.value}>
                                {formatLabel(s.value)}
                            </option>
                        ))}
                    </select>
                    {errors.rate_structure && <div className={errorClasses}>{errors.rate_structure}</div>}
                </div>
            </div>

            <div className="grid grid-cols-2 gap-3">
                <div className="flex flex-col gap-1">
                    <label className={labelClasses}>Effective Date</label>
                    <input
                        type="date"
                        name="effective_date"
                        defaultValue={rate?.effective_date ?? ''}
                        className={inputClasses}
                    />
                    {errors.effective_date && <div className={errorClasses}>{errors.effective_date}</div>}
                </div>

                <div className="flex flex-col gap-1">
                    <label className={labelClasses}>Expiration Date</label>
                    <input
                        type="date"
                        name="expiration_date"
                        defaultValue={rate?.expiration_date ?? ''}
                        className={inputClasses}
                    />
                    {errors.expiration_date && <div className={errorClasses}>{errors.expiration_date}</div>}
                </div>
            </div>

            {!isTou ? (
                <div className="flex flex-col gap-1">
                    <label className={labelClasses}>Rate</label>
                    <input
                        type="number"
                        name="rate"
                        step="0.000001"
                        min="0"
                        defaultValue={rate?.rate ?? ''}
                        className={inputClasses}
                        placeholder="0.123456"
                    />
                    {errors.rate && <div className={errorClasses}>{errors.rate}</div>}
                </div>
            ) : (
                <div className="grid grid-cols-3 gap-3">
                    <div className="flex flex-col gap-1">
                        <label className={labelClasses}>On-Peak Rate</label>
                        <input
                            type="number"
                            name="tou_rates[on_peak]"
                            step="0.000001"
                            min="0"
                            defaultValue={rate?.tou_rates?.on_peak ?? ''}
                            className={inputClasses}
                            placeholder="0.150000"
                        />
                        {errors['tou_rates.on_peak'] && (
                            <div className={errorClasses}>{errors['tou_rates.on_peak']}</div>
                        )}
                    </div>

                    <div className="flex flex-col gap-1">
                        <label className={labelClasses}>Off-Peak Rate</label>
                        <input
                            type="number"
                            name="tou_rates[off_peak]"
                            step="0.000001"
                            min="0"
                            defaultValue={rate?.tou_rates?.off_peak ?? ''}
                            className={inputClasses}
                            placeholder="0.080000"
                        />
                        {errors['tou_rates.off_peak'] && (
                            <div className={errorClasses}>{errors['tou_rates.off_peak']}</div>
                        )}
                    </div>

                    <div className="flex flex-col gap-1">
                        <label className={labelClasses}>Shoulder Rate</label>
                        <input
                            type="number"
                            name="tou_rates[shoulder]"
                            step="0.000001"
                            min="0"
                            defaultValue={rate?.tou_rates?.shoulder ?? ''}
                            className={inputClasses}
                            placeholder="Optional"
                        />
                        {errors['tou_rates.shoulder'] && (
                            <div className={errorClasses}>{errors['tou_rates.shoulder']}</div>
                        )}
                    </div>
                </div>
            )}

            <div className="flex flex-col gap-1">
                <label className={labelClasses}>Notes</label>
                <textarea
                    name="notes"
                    defaultValue={rate?.notes ?? ''}
                    rows={2}
                    className={inputClasses}
                    placeholder="Optional notes…"
                />
                {errors.notes && <div className={errorClasses}>{errors.notes}</div>}
            </div>
        </div>
    );
}

export default function StandardOfferRates({
    rates,
    utilities,
    rateClasses,
    rateStructures,
    filters,
}: Props) {
    const [editingId, setEditingId] = useState<number | null>(null);
    const [createOpen, setCreateOpen] = useState(false);
    const { sorted, sortColumn, sortDirection, toggleSort } = useSort(rates, 'effective_date');

    function applyFilter(utilityId: string) {
        router.get(
            index.url(),
            utilityId ? { utility_id: utilityId } : {},
            { preserveState: true, replace: true },
        );
    }

    return (
        <AppLayout breadcrumbs={breadcrumbs}>
            <Head title="Standard Offer Rates" />

            <h1 className="sr-only">Standard Offer Rates</h1>

            <div className="space-y-6">
                <div className="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
                    <HeadingSmall
                        title="Standard Offer Rates"
                        description="Manage published utility standard offer rates by rate class and effective period."
                    />

                    <Dialog open={createOpen} onOpenChange={setCreateOpen}>
                        <DialogTrigger asChild>
                            <button
                                type="button"
                                className="rounded-md bg-zinc-900 px-3 py-2 text-sm font-medium text-white dark:bg-zinc-100 dark:text-zinc-900"
                            >
                                Add rate
                            </button>
                        </DialogTrigger>

                        <DialogContent className="sm:max-w-lg">
                            <DialogHeader>
                                <DialogTitle>Add standard offer rate</DialogTitle>
                                <DialogDescription>
                                    Create a new standard offer rate for a utility and rate class.
                                </DialogDescription>
                            </DialogHeader>

                            <Form
                                method="post"
                                action={store.url()}
                                resetOnSuccess
                                onSuccess={() => setCreateOpen(false)}
                            >
                                {({ processing, errors }) => (
                                    <>
                                        <RateFormFields
                                            utilities={utilities}
                                            rateClasses={rateClasses}
                                            rateStructures={rateStructures}
                                            errors={errors}
                                        />

                                        <div className="mt-4 flex items-end justify-end gap-3">
                                            <button
                                                type="button"
                                                onClick={() => setCreateOpen(false)}
                                                className="rounded-md px-3 py-2 text-sm font-medium text-zinc-600 hover:text-zinc-900 dark:text-zinc-400 dark:hover:text-zinc-100"
                                            >
                                                Cancel
                                            </button>
                                            <button
                                                type="submit"
                                                disabled={processing}
                                                className="rounded-md bg-zinc-900 px-3 py-2 text-sm font-medium text-white disabled:opacity-60 dark:bg-zinc-100 dark:text-zinc-900"
                                            >
                                                Add rate
                                            </button>
                                        </div>
                                    </>
                                )}
                            </Form>
                        </DialogContent>
                    </Dialog>
                </div>

                {/* Utility filter */}
                <div className="flex items-end gap-3">
                    <div className="flex flex-col gap-1">
                        <label className={labelClasses}>Utility</label>
                        <select
                            value={filters.utility_id}
                            onChange={(e) => applyFilter(e.target.value)}
                            className={selectClasses}
                        >
                            <option value="">All utilities</option>
                            {utilities.map((u) => (
                                <option key={u.id} value={u.id}>
                                    {u.name}
                                </option>
                            ))}
                        </select>
                    </div>

                    {filters.utility_id && (
                        <button
                            type="button"
                            onClick={() => applyFilter('')}
                            className="rounded-md px-3 py-2 text-sm font-medium text-zinc-600 hover:text-zinc-900 dark:text-zinc-400 dark:hover:text-zinc-100"
                        >
                            Clear
                        </button>
                    )}
                </div>

                {/* Rates table */}
                <div className="overflow-hidden rounded-md border border-zinc-200 bg-white dark:border-zinc-800 dark:bg-zinc-950">
                    <div className="overflow-x-auto">
                        <table className="w-full text-left text-sm">
                            <thead className="border-b border-zinc-200 text-xs uppercase text-zinc-600 dark:border-zinc-800 dark:text-zinc-400">
                                <tr>
                                    <SortableHeader
                                        label="Utility"
                                        column="utility_id"
                                        sortColumn={sortColumn}
                                        sortDirection={sortDirection}
                                        onSort={toggleSort}
                                    />
                                    <SortableHeader
                                        label="Rate Class"
                                        column="rate_class"
                                        sortColumn={sortColumn}
                                        sortDirection={sortDirection}
                                        onSort={toggleSort}
                                    />
                                    <SortableHeader
                                        label="Structure"
                                        column="rate_structure"
                                        sortColumn={sortColumn}
                                        sortDirection={sortDirection}
                                        onSort={toggleSort}
                                    />
                                    <SortableHeader
                                        label="Effective"
                                        column="effective_date"
                                        sortColumn={sortColumn}
                                        sortDirection={sortDirection}
                                        onSort={toggleSort}
                                    />
                                    <SortableHeader
                                        label="Expires"
                                        column="expiration_date"
                                        sortColumn={sortColumn}
                                        sortDirection={sortDirection}
                                        onSort={toggleSort}
                                    />
                                    <th className="px-4 py-3">Rate</th>
                                    <th className="px-4 py-3" />
                                </tr>
                            </thead>
                            <tbody className="divide-y divide-zinc-200 dark:divide-zinc-800">
                                {sorted.map((r) => (
                                    <tr key={r.id}>
                                        <td className="px-4 py-3">
                                            <div className="font-medium">{r.utility?.name ?? '—'}</div>
                                            {r.utility?.state && (
                                                <div className="font-mono text-xs text-zinc-500">
                                                    {r.utility.state.code}
                                                </div>
                                            )}
                                        </td>
                                        <td className="px-4 py-3 text-xs">{formatLabel(r.rate_class)}</td>
                                        <td className="px-4 py-3 text-xs text-zinc-600 dark:text-zinc-400">
                                            {formatLabel(r.rate_structure)}
                                        </td>
                                        <td className="px-4 py-3 font-mono text-xs">{r.effective_date}</td>
                                        <td className="px-4 py-3 font-mono text-xs">
                                            {r.expiration_date ?? (
                                                <span className="text-green-700 dark:text-green-400">
                                                    Current
                                                </span>
                                            )}
                                        </td>
                                        <td className="px-4 py-3 font-mono text-xs">{formatRate(r)}</td>
                                        <td className="px-4 py-3 text-right">
                                            <div className="flex items-center justify-end gap-4">
                                                <Dialog
                                                    open={editingId === r.id}
                                                    onOpenChange={(open) => setEditingId(open ? r.id : null)}
                                                >
                                                    <DialogTrigger asChild>
                                                        <button
                                                            type="button"
                                                            className="text-sm text-zinc-700 hover:underline dark:text-zinc-300"
                                                        >
                                                            Edit
                                                        </button>
                                                    </DialogTrigger>

                                                    <DialogContent className="sm:max-w-lg">
                                                        <DialogHeader>
                                                            <DialogTitle>Edit standard offer rate</DialogTitle>
                                                            <DialogDescription>
                                                                Update the rate for {r.utility?.name} —{' '}
                                                                {formatLabel(r.rate_class)}.
                                                            </DialogDescription>
                                                        </DialogHeader>

                                                        <Form
                                                            method="put"
                                                            action={update.url(r.id)}
                                                            onSuccess={() => setEditingId(null)}
                                                        >
                                                            {({ processing, errors }) => (
                                                                <>
                                                                    <RateFormFields
                                                                        rate={r}
                                                                        utilities={utilities}
                                                                        rateClasses={rateClasses}
                                                                        rateStructures={rateStructures}
                                                                        errors={errors}
                                                                    />

                                                                    <div className="mt-4 flex items-end justify-end gap-3">
                                                                        <button
                                                                            type="button"
                                                                            onClick={() => setEditingId(null)}
                                                                            className="rounded-md px-3 py-2 text-sm font-medium text-zinc-600 hover:text-zinc-900 dark:text-zinc-400 dark:hover:text-zinc-100"
                                                                        >
                                                                            Cancel
                                                                        </button>
                                                                        <button
                                                                            type="submit"
                                                                            disabled={processing}
                                                                            className="rounded-md bg-zinc-900 px-3 py-2 text-sm font-medium text-white disabled:opacity-60 dark:bg-zinc-100 dark:text-zinc-900"
                                                                        >
                                                                            Save
                                                                        </button>
                                                                    </div>
                                                                </>
                                                            )}
                                                        </Form>
                                                    </DialogContent>
                                                </Dialog>

                                                <Form method="delete" action={destroy.url(r.id)}>
                                                    {({ processing }) => (
                                                        <button
                                                            type="submit"
                                                            disabled={processing}
                                                            className="text-sm text-red-700 hover:underline disabled:opacity-60 dark:text-red-400"
                                                        >
                                                            Delete
                                                        </button>
                                                    )}
                                                </Form>
                                            </div>
                                        </td>
                                    </tr>
                                ))}
                            </tbody>
                        </table>
                    </div>

                    {rates.length === 0 && (
                        <div className="p-4 text-sm text-zinc-600 dark:text-zinc-400">
                            No standard offer rates yet.
                        </div>
                    )}
                </div>
            </div>
        </AppLayout>
    );
}
