import { mdiArrowLeft, mdiChartTimelineVariant, mdiContentSaveOutline, mdiEyeOutline } from '@mdi/js';
import Head from 'next/head';
import React, { ReactElement, useEffect, useMemo, useState } from 'react';
import DatePicker from 'react-datepicker';
import 'react-datepicker/dist/react-datepicker.css';
import dayjs from 'dayjs';
import { Field, Form, Formik } from 'formik';
import BaseButton from '../../components/BaseButton';
import BaseButtons from '../../components/BaseButtons';
import BaseDivider from '../../components/BaseDivider';
import CardBox from '../../components/CardBox';
import FormField from '../../components/FormField';
import { RichTextField } from '../../components/RichTextField';
import SectionMain from '../../components/SectionMain';
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton';
import { SelectField } from '../../components/SelectField';
import { getPageTitle } from '../../config';
import dataFormatter from '../../helpers/dataFormatter';
import { humanize } from '../../helpers/humanize';
import { hasPermission } from '../../helpers/userPermissions';
import LayoutAuthenticated from '../../layouts/Authenticated';
import { useAppDispatch, useAppSelector } from '../../stores/hooks';
import { fetch, update } from '../../stores/projects/projectsSlice';
import { useRouter } from 'next/router';

const baseInitialValues = {
  organization: null,
  program: null,
  province: null,
  budget_line: null,
  name: '',
  project_code: '',
  implementing_entity: '',
  objectives: '',
  start_date: null,
  end_date: null,
  planned_budget: '',
  currency: '',
  completion_percent: '',
  status: '',
  risk_level: '',
  reporting_cycle: '',
  last_reported_at: null,
};

const toDateValue = (value?: string | Date | null) => {
  if (!value) {
    return null;
  }

  const date = new Date(value);
  return Number.isNaN(date.getTime()) ? null : date;
};

const formatDisplayDate = (value?: string | Date | null) => {
  if (!value) {
    return 'Not set';
  }

  const date = dayjs(value);
  return date.isValid() ? date.format('DD MMM YYYY') : 'Not set';
};

const normalizeProject = (project: any) => ({
  ...baseInitialValues,
  ...project,
  organization: project?.organization || null,
  program: project?.program || null,
  province: project?.province || null,
  budget_line: project?.budget_line || null,
  start_date: project?.start_date || null,
  end_date: project?.end_date || null,
  last_reported_at: project?.last_reported_at || null,
});

const SectionBlock = ({
  title,
  description,
  children,
}: {
  title: string;
  description: string;
  children: React.ReactNode;
}) => (
  <div className="rounded-xl border border-slate-200/80 p-5 dark:border-dark-700">
    <h3 className="text-lg font-semibold text-slate-900 dark:text-slate-100">{title}</h3>
    <p className="mt-1 text-sm text-slate-600 dark:text-slate-300">{description}</p>
    <div className="mt-6">{children}</div>
  </div>
);

const EditProjectsPage = () => {
  const router = useRouter();
  const dispatch = useAppDispatch();
  const { projects } = useAppSelector((state) => state.projects);
  const { currentUser } = useAppSelector((state) => state.auth);
  const { id } = router.query;
  const [initialValues, setInitialValues] = useState(baseInitialValues);

  useEffect(() => {
    if (id) {
      dispatch(fetch({ id }));
    }
  }, [dispatch, id]);

  useEffect(() => {
    if (projects && !Array.isArray(projects)) {
      setInitialValues(normalizeProject(projects));
    }
  }, [projects]);

  const projectName = useMemo(() => {
    return initialValues.name || 'Edit project';
  }, [initialValues.name]);

  const handleSubmit = async (values: typeof baseInitialValues) => {
    await dispatch(
      update({
        id,
        data: dataFormatter.dataGridEditFormatter(values),
      }),
    );
    await router.push('/projects/projects-list');
  };

  return (
    <>
      <Head>
        <title>{getPageTitle('Edit project')}</title>
      </Head>
      <SectionMain>
        <SectionTitleLineWithButton icon={mdiChartTimelineVariant} title={projectName} main>
          <BaseButtons type="justify-start md:justify-end" className="w-full md:w-auto" noWrap>
            <BaseButton color="white" outline icon={mdiArrowLeft} label="Back to list" onClick={() => router.push('/projects/projects-list')} />
            <BaseButton color="white" outline icon={mdiEyeOutline} label="View project" href={`/projects/projects-view/?id=${id}`} />
          </BaseButtons>
        </SectionTitleLineWithButton>

        <CardBox>
          <Formik enableReinitialize initialValues={initialValues} onSubmit={handleSubmit}>
            {({ values, setFieldValue }) => (
              <Form>
                <div className="flex flex-col gap-6 xl:flex-row xl:items-start">
                  <div className="flex-1 space-y-6">
                    <SectionBlock
                      title="Identity and ownership"
                      description="Keep the project anchored to the correct organization, program, geography, and budget line."
                    >
                      <div className="grid gap-6 md:grid-cols-2">
                        {hasPermission(currentUser, 'READ_ORGANIZATIONS') && (
                          <FormField label="Organization" labelFor="organization" help="Choose the owning organization for this project.">
                            <Field
                              name="organization"
                              id="organization"
                              component={SelectField}
                              options={values.organization}
                              itemRef={'organizations'}
                              showField={'name'}
                            />
                          </FormField>
                        )}

                        <FormField label="Program" labelFor="program" help="Link the project to the wider delivery program.">
                          <Field
                            name="program"
                            id="program"
                            component={SelectField}
                            options={values.program}
                            itemRef={'programs'}
                            showField={'name'}
                          />
                        </FormField>

                        <FormField label="Province" labelFor="province" help="Use the operating province used in reporting and rollout views.">
                          <Field
                            name="province"
                            id="province"
                            component={SelectField}
                            options={values.province}
                            itemRef={'provinces'}
                            showField={'name'}
                          />
                        </FormField>

                        <FormField label="Budget line" labelFor="budget_line" help="Assign the budget line that funds the project.">
                          <Field
                            name="budget_line"
                            id="budget_line"
                            component={SelectField}
                            options={values.budget_line}
                            itemRef={'budget_lines'}
                            showField={'name'}
                          />
                        </FormField>

                        <FormField label="Project name" labelFor="name" help="Use a clear name that works in dashboards and reports.">
                          <Field name="name" id="name" placeholder="Project name" />
                        </FormField>

                        <FormField label="Project code" labelFor="project_code" help="Internal code, donor code, or implementation reference.">
                          <Field name="project_code" id="project_code" placeholder="Project code" />
                        </FormField>
                      </div>
                    </SectionBlock>

                    <SectionBlock
                      title="Delivery and scope"
                      description="Document the lead implementer and the strategic objectives that define success."
                    >
                      <div className="grid gap-6">
                        <FormField label="Implementing entity" labelFor="implementing_entity" help="Entity or partner accountable for executing the work.">
                          <Field name="implementing_entity" id="implementing_entity" placeholder="Implementing entity" />
                        </FormField>

                        <FormField
                          label="Objectives"
                          labelFor="objectives"
                          hasTextareaHeight
                          help="Summarize intended outcomes, delivery scope, and any key implementation notes."
                        >
                          <Field name="objectives" id="objectives" component={RichTextField} />
                        </FormField>
                      </div>
                    </SectionBlock>

                    <SectionBlock
                      title="Execution and reporting"
                      description="Set the delivery window and the cadence used for management reporting."
                    >
                      <div className="grid gap-6 md:grid-cols-2">
                        <FormField label="Start date" labelFor="start_date" help="Planned or actual commencement date for project delivery.">
                          <DatePicker
                            id="start_date"
                            dateFormat="yyyy-MM-dd HH:mm"
                            showTimeSelect
                            selected={toDateValue(values.start_date)}
                            onChange={(date) => setFieldValue('start_date', date || null)}
                            placeholderText="Select start date"
                          />
                        </FormField>

                        <FormField label="End date" labelFor="end_date" help="Expected completion date or latest approved end date.">
                          <DatePicker
                            id="end_date"
                            dateFormat="yyyy-MM-dd HH:mm"
                            showTimeSelect
                            selected={toDateValue(values.end_date)}
                            onChange={(date) => setFieldValue('end_date', date || null)}
                            placeholderText="Select end date"
                          />
                        </FormField>

                        <FormField label="Reporting cycle" labelFor="reporting_cycle" help="Examples: weekly, monthly, quarterly.">
                          <Field name="reporting_cycle" id="reporting_cycle" placeholder="Monthly" />
                        </FormField>

                        <FormField label="Last reported at" labelFor="last_reported_at" help="Most recent reporting checkpoint or status refresh.">
                          <DatePicker
                            id="last_reported_at"
                            dateFormat="yyyy-MM-dd HH:mm"
                            showTimeSelect
                            selected={toDateValue(values.last_reported_at)}
                            onChange={(date) => setFieldValue('last_reported_at', date || null)}
                            placeholderText="Select last report date"
                          />
                        </FormField>
                      </div>
                    </SectionBlock>

                    <SectionBlock
                      title="Budget and controls"
                      description="Maintain the planning budget, delivery status, and risk posture used across reporting views."
                    >
                      <div className="grid gap-6 md:grid-cols-2">
                        <FormField label="Planned budget" labelFor="planned_budget" help="Total planned budget for this project.">
                          <Field type="number" name="planned_budget" id="planned_budget" placeholder="0" />
                        </FormField>

                        <FormField label="Currency" labelFor="currency" help="Reporting currency for the planned budget.">
                          <Field name="currency" id="currency" component="select">
                            <option value="">Select currency</option>
                            <option value="CDF">CDF</option>
                            <option value="USD">USD</option>
                          </Field>
                        </FormField>

                        <FormField label="Completion percent" labelFor="completion_percent" help="Enter delivery progress as a whole number percentage.">
                          <Field type="number" name="completion_percent" id="completion_percent" placeholder="0" min="0" max="100" />
                        </FormField>

                        <FormField label="Status" labelFor="status" help="Operational lifecycle state shown on dashboards and worklists.">
                          <Field name="status" id="status" component="select">
                            <option value="">Select status</option>
                            <option value="draft">Draft</option>
                            <option value="submitted">Submitted</option>
                            <option value="approved">Approved</option>
                            <option value="active">Active</option>
                            <option value="on_hold">On hold</option>
                            <option value="completed">Completed</option>
                            <option value="closed">Closed</option>
                          </Field>
                        </FormField>

                        <FormField label="Risk level" labelFor="risk_level" help="Current risk posture for executive and operational reporting.">
                          <Field name="risk_level" id="risk_level" component="select">
                            <option value="">Select risk level</option>
                            <option value="low">Low</option>
                            <option value="medium">Medium</option>
                            <option value="high">High</option>
                            <option value="critical">Critical</option>
                          </Field>
                        </FormField>
                      </div>
                    </SectionBlock>
                  </div>

                  <div className="w-full xl:max-w-sm">
                    <div className="space-y-6 xl:sticky xl:top-6">
                      <div className="rounded-xl border border-slate-200/80 bg-slate-50/80 p-5 dark:border-dark-700 dark:bg-dark-800/50">
                        <p className="text-xs font-semibold uppercase tracking-[0.2em] text-slate-500 dark:text-slate-400">Live summary</p>
                        <h3 className="mt-3 text-xl font-semibold text-slate-900 dark:text-slate-100">{values.name || 'Project draft'}</h3>
                        <div className="mt-4 space-y-4 text-sm text-slate-600 dark:text-slate-300">
                          <div>
                            <p className="text-xs font-semibold uppercase tracking-[0.15em] text-slate-500 dark:text-slate-400">Status</p>
                            <p className="mt-1 font-medium text-slate-900 dark:text-slate-100">{values.status ? humanize(values.status) : 'Not set'}</p>
                          </div>
                          <div>
                            <p className="text-xs font-semibold uppercase tracking-[0.15em] text-slate-500 dark:text-slate-400">Risk level</p>
                            <p className="mt-1 font-medium text-slate-900 dark:text-slate-100">{values.risk_level ? humanize(values.risk_level) : 'Not set'}</p>
                          </div>
                          <div>
                            <p className="text-xs font-semibold uppercase tracking-[0.15em] text-slate-500 dark:text-slate-400">Timeline</p>
                            <p className="mt-1 font-medium text-slate-900 dark:text-slate-100">
                              {formatDisplayDate(values.start_date)} → {formatDisplayDate(values.end_date)}
                            </p>
                          </div>
                          <div>
                            <p className="text-xs font-semibold uppercase tracking-[0.15em] text-slate-500 dark:text-slate-400">Budget</p>
                            <p className="mt-1 font-medium text-slate-900 dark:text-slate-100">
                              {values.planned_budget || '0'} {values.currency || ''}
                            </p>
                          </div>
                          <div>
                            <p className="text-xs font-semibold uppercase tracking-[0.15em] text-slate-500 dark:text-slate-400">Completion</p>
                            <p className="mt-1 font-medium text-slate-900 dark:text-slate-100">{values.completion_percent || '0'}%</p>
                          </div>
                        </div>
                      </div>

                      <div className="rounded-xl border border-slate-200/80 p-5 dark:border-dark-700">
                        <h3 className="text-lg font-semibold text-slate-900 dark:text-slate-100">Editing guidance</h3>
                        <ul className="mt-4 space-y-3 text-sm leading-6 text-slate-600 dark:text-slate-300">
                          <li>Keep the project name and code consistent with the records used in approvals, contracts, and reporting.</li>
                          <li>Use the reporting cycle and last reported date together so dashboards reflect current operating cadence.</li>
                          <li>Completion percent, status, and risk level are most valuable when they are updated together.</li>
                        </ul>
                      </div>
                    </div>
                  </div>
                </div>

                <BaseDivider />

                <BaseButtons>
                  <BaseButton type="submit" color="info" icon={mdiContentSaveOutline} label="Save project" />
                  <BaseButton type="reset" color="info" outline label="Reset changes" />
                  <BaseButton type="button" color="white" outline label="View project" href={`/projects/projects-view/?id=${id}`} />
                  <BaseButton type="button" color="danger" outline label="Cancel" onClick={() => router.push('/projects/projects-list')} />
                </BaseButtons>
              </Form>
            )}
          </Formik>
        </CardBox>
      </SectionMain>
    </>
  );
};

EditProjectsPage.getLayout = function getLayout(page: ReactElement) {
  return <LayoutAuthenticated permission={'UPDATE_PROJECTS'}>{page}</LayoutAuthenticated>;
};

export default EditProjectsPage;
